我正在构建一个函数,我想创建一个由值0,1和2组成的随机20x20数组。我其次想要遍历数组并计算每个数字中有多少个阵列。这是我的代码:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import random
def my_array():
rand_array = np.random.randint(0,3,(20,20))
zeros = 0
ones = 0
twos = 0
for element in rand_array:
if element == 0:
zeros += 1
elif element == 1:
ones += 1
else:
twos += 1
return rand_array,zeros,ones,twos
print(my_array())
当我取消for循环以尝试迭代数组时,它工作正常并打印数组,但是代码会给出此错误消息:
ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()
答案 0 :(得分:4)
当您迭代多维numpy
数组时,您只会迭代第一维。在您的示例中,您的element
值也将是1维数组!
您可以使用另一个for
循环解决1维数组值的问题,但在numpy
代码中,使用for
循环通常是一个坏主意。您通常希望在整个阵列中使用向量操作和操作广播。
在您的示例中,您可以执行以下操作:
rand_array = np.random.randint(0,3,(20,20))
# no loop needed
zeros = np.sum(rand_array == 0)
ones = np.sum(rand_array == 1)
twos = np.sum(rand_array == 2)
==
运算符在整个数组上广播,生成一个布尔数组。然后sum
将True
值(True
等于Python中的1
)相加以获得计数。
答案 1 :(得分:2)
正如已经指出的那样,你在迭代行而不是元素。而numpy
只是拒绝评估array
的真实性,除了数组只包含一个元素。
如果您想迭代每个元素,我建议使用np.nditer
。这样您就可以访问每个元素,无论您的数组有多少维度。你只需改变这一行:
for element in np.nditer(rand_array):
# instead of "for element in rand_array:"
但我认为还有一种更好的方法:如果你有一个包含离散值的数组(如整数),你可以使用np.histogram
来计算你的数量。
您需要设置bin,以便每个整数都有自己的bin:
bins = np.arange(np.min(rand_array)-0.5, np.max(rand_array)+1.5)
# in your case this will give an array containing [-0.5, 0.5, 1.5, 2.5]
这样直方图将使用-0.5
和0.5
之间的每个值填充第一个bin(所以数组中每0
个),第二个bin的所有值都在{{1 }和0.5
(每1.5
),依此类推。然后调用直方图函数来获取计数:
1
这种方法的优点是您不需要对您的值进行硬编码(因为它们将在counts, _ = np.histogram(rand_array, bins=bins)
print(counts) # [130 145 125] # So 130 zeros, 145 ones, 125 twos
内计算)。
<小时/> 如评论中所示,您无需将邮箱设置为
bins
。您可以使用简单的float
- 二进制位:
integer
答案 2 :(得分:0)
for循环遍历行,因此您必须为每一行插入另一个循环:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import random
def my_array():
rand_array = np.random.randint(0,3,(20,20))
zeros = 0
ones = 0
twos = 0
for element in rand_array:
for el in element:
if el == 0:
zeros += 1
elif el == 1:
ones += 1
else:
twos += 1
return rand_array,zeros,ones,twos
return rand_array
print(my_array())