二维数组的np.where()行为

时间:2019-06-20 18:45:24

标签: python numpy dictionary

我有一个numpy的2d数组,每个数组元素都包含一个字典。

[[{'foo': 1} {'bar': 2, 'xyz': 7} {} {}]
 [{} {'xyz': 7} {'bar': 2} {'foo': 1}]
 [{} {'xyz': 7} {'foo': 1} {'bar': 2}]]

我正在尝试为字典包含给定键的每一行返回所有索引。

我当前的解决方案如下:

indices = []
for row in arr:
  for i in range(len(row)):
    if 'foo' in row[i].keys():
      indices.append(i)

并返回

[0, 3, 2]

但是我想知道是否还有更好的方法可以使用np.where()

来编写它

我发现这几乎是我想要的

np.where([[['foo' in ele.keys()] for ele in row] for row in arr])

但是它返回3个数组(中间的是正确的数组)

(array([0, 1, 2]), array([0, 3, 2]), array([0, 0, 0]))

我不了解第一个和第三个数组,为什么要创建它们?

2 个答案:

答案 0 :(得分:1)

In [226]: [[['foo' in ele.keys()] for ele in row] for row in arr]                                    
Out[226]: 
[[[True], [False], [False], [False]],
 [[False], [False], [False], [True]],
 [[False], [False], [True], [False]]]

制作一个数组,给出一个形状(3,4,1)。 where返回一个数组元组,每个维一个。

使用分组()代替[],得到2d数组:

In [227]: [[('foo' in ele.keys()) for ele in row] for row in arr]                                    
Out[227]: 
[[True, False, False, False],
 [False, False, False, True],
 [False, False, True, False]]

frompyfunc是将函数应用于数组的每个元素的另一种方法。它往往比显式循环快一些(最多2倍),并且在使用对象dtype数组时特别好:

In [228]: np.frompyfunc(lambda d: 'foo' in d.keys(),1,1)(arr)                                        
Out[228]: 
array([[True, False, False, False],
       [False, False, False, True],
       [False, False, True, False]], dtype=object)
In [229]: np.where(_)                                                                                
Out[229]: (array([0, 1, 2]), array([0, 3, 2]))

答案 1 :(得分:0)

您还可以使用此:

x = [[{'foo': 1},{'bar': 2, 'xyz': 7},{},{}],
     [{} ,{'xyz': 7} ,{'bar': 2} ,{'foo': 1}],
     [{}, {'xyz': 7}, {'foo': 1}, {'bar': 2}]]

res = [list(map(lambda elem: 'foo' in elem.keys(),item)) for item in x]
print(res)
print(numpy.where(res))

输出:

[[True, False, False, False],
 [False, False, False, True],
 [False, False, True, False]]

(array([0, 1, 2], dtype=int64), array([0, 3, 2], dtype=int64))