如何使用numpy rec数组中的表达式搜索行

时间:2016-06-30 04:56:34

标签: python numpy

考虑我有一个numpy recarray如下:

r = np.rec.array([(1,2,'Hello'),(2,3,"World")], \
                 dtype=[('foo', 'i4'),('bar', 'i4'), ('baz', 'S10')])

现在我想得到所有对于存储在dict中的以下表达式返回'True'的对象,

expression = {'foo':1,'bar':3.,'baz':'Hello'}
  

我正在寻找像 r.select(** expression)这样的方法来选择符合传递给select的那些条件的所有对象。

表达是动态的,经常变化。

2 个答案:

答案 0 :(得分:1)

您可以将数组比较与布尔运算符结合使用。 例如(使用浮动比较的穷人实现):

EPS = 1e-7
mask = np.ones(len(r), dtype=np.bool)
mask &= r['foo'] == 1
mask &= (r['bar'] > 3-EPS) & (r['bar'] < 3+EPS)
mask &= r['baz'] == 'hello'
print(r[mask])

如果您愿意,也可以使用或|代替和&。 (或者是一个组合,因为两个r['bar']无论如何都必须是&。)

答案 1 :(得分:0)

如果r为1d(或可以展平),np.in1d是一种快速搜索工具。大多数示例都是使用整数,但它也适用于复合dtype。

In [1127]: r = np.rec.array([(1,2,'Hello'),(2,3,"World")], \
   ......:                  dtype=[('foo', 'i4'),('bar', 'i4'), ('baz', 'S10')]) 

In [1129]: r.shape
Out[1129]: (2,)

In [1130]: expression = {'foo':1,'bar':3.,'baz':'Hello'}

从此expression创建1个元素数组:

In [1131]: x=np.array((expression['foo'],expression['bar'],expression['baz']), dtype=r.dtype)

In [1132]: x
Out[1132]: 
array((1, 3, b'Hello'), 
      dtype=(numpy.record, [('foo', '<i4'), ('bar', '<i4'), ('baz', 'S10')]))

In [1133]: np.in1d(r,x)
Out[1133]: array([False, False], dtype=bool)

让我们展开r以包含匹配项:

In [1134]: r1 = np.rec.array([(1,2,'Hello'),(1,3,'Hello'),(2,3,"World")], \
                 dtype=[('foo', 'i4'),('bar', 'i4'), ('baz', 'S10')])

In [1135]: np.in1d(r1,x)
Out[1135]: array([False,  True, False], dtype=bool)

我可以通过迭代expression

来构造dtype.names数组
In [1138]: tuple([expression[n] for n in r.dtype.names])
Out[1138]: (1, 3.0, 'Hello')

In [1139]: x=np.array(tuple([expression[n] for n in r.dtype.names]), dtype=r.dtype)

我建议也看一下recfunctions

from numpy.lib import recfunctions

阅读其中一些代码,了解开发人员希望我们如何处理结构化数组。