代码之家  ›  专栏  ›  技术社区  ›  maynull

如何从numpy数组中提取满足多个条件的行?

  •  1
  • maynull  · 技术社区  · 6 年前

    我想从另一个数组中提取满足多个条件的行。

    这是原始阵列的外观:

    original = array([[Timestamp('2018-01-15 01:59:00'), 329, 30, 5],
                      [Timestamp('2018-01-15 01:59:00'), 326, 25, 3],
                      [Timestamp('2018-01-15 02:00:00'), 324, 22, 34],
                      ..., 
                      [Timestamp('2018-01-15 21:57:00'), 322, 23, 3],
                      [Timestamp('2018-01-15 21:57:00'), 323, 30, 9],
                      [Timestamp('2018-01-15 21:59:00'), 323, 1, 19]], dtype=object)
    

    条件包括:
    1) 第三个或第四个值大于25。
    2) 第三个或第四个值比另一个值大两倍。
    3) 值在01:00至06:00之间接收

    因此,根据条件,将提取第一行。(30大于25 | 30大于5 |的两倍以上排在01:59:00,即01:00至06:00之间)

    是否可以仅使用 np.where ?

    编辑 :我可以和熊猫一起做这项工作。

    >>> df_text = pd.DataFrame( trade_reset , columns=['date', 'freq', 'in', 'out'])
    
    >>> df_text = df_text[(df_text['in'] >= 30 ) | (df_text['out'] >= 30 )]
    
    >>> df_text = df_text[(df_text['in'] > df_text['out']*2 ) | (df_text['out'] >= df_text['in']*2 )]
    
    >>> df_text[ (df_text['date'] < datetime(2018, 1, 15, 6)) & (df_text['date'] > datetime(2018, 1, 15, 1)) ]
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   hpaulj    6 年前

    为方便起见,请定义 Timestamp 作为一个 np.datetie64 造物主:

    In [492]: Timestamp=lambda x: np.datetime64(x, 's')
    In [493]: Timestamp('2018-01-15 01:59:00')
    Out[493]: numpy.datetime64('2018-01-15T01:59:00')
    In [494]: original = np.array([[Timestamp('2018-01-15 01:59:00'), 329, 30, 5],
         ...:                   [Timestamp('2018-01-15 01:59:00'), 326, 25, 3],
         ...:                   [Timestamp('2018-01-15 02:00:00'), 324, 22, 34],
         ...:                   [Timestamp('2018-01-15 21:57:00'), 322, 23, 3],
         ...:                   [Timestamp('2018-01-15 21:57:00'), 323, 30, 9],
         ...:                   [Timestamp('2018-01-15 21:59:00'), 323, 1, 19]], dty
         ...: pe=object)
         ...:                   
    In [495]: original
    Out[495]: 
    array([[numpy.datetime64('2018-01-15T01:59:00'), 329, 30, 5],
           [numpy.datetime64('2018-01-15T01:59:00'), 326, 25, 3],
           [numpy.datetime64('2018-01-15T02:00:00'), 324, 22, 34],
           [numpy.datetime64('2018-01-15T21:57:00'), 322, 23, 3],
           [numpy.datetime64('2018-01-15T21:57:00'), 323, 30, 9],
           [numpy.datetime64('2018-01-15T21:59:00'), 323, 1, 19]],
          dtype=object)
    

    现在,我们可以通过以下方式进行时间测试:

    In [500]: original[:,0]<Timestamp('2018-01-15 06:00:00')
    Out[500]: array([ True,  True,  True, False, False, False])
    In [501]: original[:,0]>Timestamp('2018-01-15 01:00:00')
    Out[501]: array([ True,  True,  True,  True,  True,  True])
    In [502]: mask = Out[500] & Out[501]
    In [503]: mask
    Out[503]: array([ True,  True,  True, False, False, False])
    

    第2列测试(&A);3.

    In [509]: (original[:,[2,3]]>=30).any(axis=1)
    Out[509]: array([ True, False,  True, False,  True, False])
    

    In [506]: (original[:,2]>(original[:,3]*2)) | (original[:,3]>=(original[:,2]*2))
         ...: 
    Out[506]: array([ True,  True, False,  True,  True,  True])
    

    并且一起

    In [510]: mask & Out[509] & Out[506]
    Out[510]: array([ True, False, False, False, False, False])
    In [511]: np.where(Out[510])
    Out[511]: (array([0]),)
    

    有时 object 数据类型妨碍计算,通常它是一个函数不能将任务委托给对象的方法。这里可以比较Python整数,因此也可以比较对象数组。在大型数组中,如果先将数组的一部分转换为二维数字数组,则这些比较可能会更快。

    In [512]: original[:,1:].astype(int)
    Out[512]: 
    array([[329,  30,   5],
           [326,  25,   3],
           [324,  22,  34],
           [322,  23,   3],
           [323,  30,   9],
           [323,   1,  19]])
    

    熊猫似乎更乐于处理对象数据类型,但我认为灵活性是以速度为代价的。