【问题标题】:How to find negative elements in a multidimensional array? Use .any() .all() correctly如何在多维数组中找到负元素?正确使用 .any() .all()
【发布时间】:2016-01-23 04:58:50
【问题描述】:

我有一个带有负 double 元素的 numpy 数组 arr。它的形状为(1000,1000)。由于元素很复杂,我们使用arr.real 仅评估实部。

我第一次尝试

for i in arr.real:
    if i < 0:
        print(i)

这给出了以下 ValueError:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

但是,如果我尝试

for i in arr.real:
    if i.any() < 0:
        print(i)

for i in arr.real:
    if i.all() < 0:
        print(i)

没有输出。即使确实存在负值,也不会打印任何内容。

我该如何纠正这个问题?我有什么误解?

编辑:

for i in arr.real:
    print(i[i<0])

确实有效。但是,如何搜索两个条件?例如,

i < 0 and i > -1e-12

【问题讨论】:

  • 正确的方法是(i &lt; 0).any()。与.all()类似。
  • @Divakar 谢谢。你能给我解释一下区别吗? (i &lt; 0).any() 似乎输出正值
  • 好吧,iarr 的一部分,因此i.any() 不会真正反映您在arr 中寻找负面元素的想法。这就是为什么第二种方法不起作用的原因。第一个不起作用,因为 i 仍然不是标量。
  • for i in arr: if (i &lt; 0).any(): print(i) 这会在数组中输出正值(最初是复杂的)。这样做的正确方法是什么?
  • 您是说您正在处理具有复数的数组吗?那么,如何定义正值,因为会有实部和虚部?然后,比较真实和想象。部分并根据您对积极的定义继续进行。

标签: python arrays numpy multidimensional-array


【解决方案1】:

由于arr 是二维的,因此迭代会为您提供行,而不是元素。

制作一个样本数组:

In [347]: arr=np.arange(16).reshape(4,4)-10
In [348]: arr
Out[348]: 
array([[-10,  -9,  -8,  -7],
       [ -6,  -5,  -4,  -3],
       [ -2,  -1,   0,   1],
       [  2,   3,   4,   5]])

迭代一些打印:

In [350]: for i in arr:
   print(i)
   print(i<0)
   print((i<0).any())
   .....: 

结果:

[-10  -9  -8  -7]
[ True  True  True  True]
True
[-6 -5 -4 -3]
[ True  True  True  True]
True
[-2 -1  0  1]
[ True  True False False]
True
[2 3 4 5]
[False False False False]
False

当您尝试在 if 语句中使用该布尔数组 np.array([True, True, False, False]) 时,ValueError 结果。将 allany 应用于数组会将其减少为一个标量 True/False 值,这适用于 if 语句。

您可以将negative 测试应用于整个数组,并将all/any 应用于行(或列) - 无需迭代:

In [351]: arr<0
Out[351]: 
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True, False, False],
       [False, False, False, False]], dtype=bool)
In [352]: (arr<0).any(axis=1)
Out[352]: array([ True,  True,  True, False], dtype=bool)
In [353]: (arr<0).all(axis=1)
Out[353]: array([ True,  True, False, False], dtype=bool)

要获取数组中的非负值,您可以使用此布尔掩码(或其负数):

In [354]: arr[arr>=0]
Out[354]: array([0, 1, 2, 3, 4, 5])

因为每行中有不同数量的有效值,它不能给你一个二维数组。

但是您可以返回迭代以获取每行的值列表。这里我使用列表推导来进行迭代。

In [355]: [a[a>=0] for a in arr]
Out[355]: 
[array([], dtype=int32),
 array([], dtype=int32),
 array([0, 1]),
 array([2, 3, 4, 5])]

【讨论】:

  • 对于我上面提到的两个条件,我认为(i[i&lt;0 | i &gt; some_arbitrary_value]) for i in arr 会起作用。是否有一种标准方法可以在多个条件下进行列表推导?
  • 只要表达式产生您想要的值,它就可以在列表推导中使用。使用 () 删除任何歧义。对于更复杂的表达式,定义一个简单的函数来进行计算:[foo(x) for x in ...]
【解决方案2】:

你尝试过 lambda 表达式吗?

for k in arr:
     print filter(lambda x: x < 0, k)

如果你的“数组”是一个带有元组键的字典,你可以像这样使用 lambda:

d = {(0,0):-3,(0,1):3,(0,2):-3.7,(0,3):0,
(1,0):30,(1,1):-12,(1,2):-0.1,(1,3):2.5,}

keys = filter(lambda x: d[x] < 0, [k for k in d])

print [d[keys[n]] for n in range(0,len(keys))]

也许真正回答你的问题,这会有所帮助,

import itertools as it
aK = it.product(range(0,len(arr)),range(0,len(arr)))

negKeys = filter(lambda x: arr[x[0]][x[1]] < 0, [k for k in ak])
negVals = [arr[k[0]][k[1]] for k in negKeys]

【讨论】:

  • 这会输出&lt;filter object at 0x107219400&gt;
  • 对不起,我必须解决这个问题
  • 输出相同。
  • 嗯,Arr 的类型是什么?还有 [type(k) for k in arr] 是什么?
  • arr 是一个 numpy 数组
【解决方案3】:

似乎一种方法是:

for row in arr.real:
    for i in row:
        if (i<0 and i<-1e-10):
            print(i)

【讨论】:

  • 要测试和打印二维数组的单个元素,您需要这个嵌套循环,或者遍历 1d arr.ravel() 视图。但通常你不想显式地迭代一个数组。那很慢。让numpy 在快速编译的代码中进行迭代。
猜你喜欢
  • 1970-01-01
  • 2010-10-17
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多