Python中sum函数的用法

3
x_d = np.linspace(-4, 8, 30)

print('x_d shape: ',x_d.shape)
print('x shape: ',x.shape)


density = sum((abs(xi - x_d) < 0.5) for xi in x)---------> difficulty in understanding statement

output:

x_d shape:  (30,)
x shape:  (20,)

我很难理解上述陈述。

对于每个x值,我们从中减去x_d,然后得到单个值。但我们的密度为(30,)。

我们如何得到密度维度为(30,)?

1个回答

3

表达式

xi - x_d

将使用NumPy broadcasting 来使两个对象的形状一致。在这种情况下,这意味着将标量值xi视为与 x_d 相同维度的所有相同值的数组。 abs 函数和小于比较将逐元素地作用于NumPy数组,因此表达式
(abs(xi - x_d) < 0.5)

应该得到一个长度为30的数组(与x_d相同大小),其中该数组的每个条目都是TrueFalse,具体取决于应用于x_d的每个元素的条件。

这将针对多个xi值重复进行,导致多个不同的长度为30的数组。

调用sum函数的结果是它们逐个元素相加(也因广播的运气而相加,因为sum函数具有默认初始值0,第一个数组被逐个元素加到0上,保持不变)。

因此,在最终结果中,它将是一个长度为30的数组,其中数组的第0项计算了多少个xi值满足基于x_d的第0个元素的绝对值条件。输出数组的项目1将计算满足基于x_d的第1个元素的绝对值条件的xi值的数量,依此类推。

以下是一些测试数据的示例:

In [31]: x_d = np.linspace(-4, 8, 30)

In [32]: x = np.arange(20)

In [33]: x
Out[33]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19])

In [34]: density = sum((abs(xi - x_d) < 0.5) for xi in x)

In [35]: density
Out[35]: 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1])

感谢您的回复。我不明白这个语句的意思。“这将针对多个xi值重复进行,从而导致多个不同长度为30的数组”。在这种情况下,for循环针对x的每个元素重复执行,因此我们得到了20个形状为(30,)的数组列表,对于每个x的元素,我们正在对所有形状为(30)的20个数组进行求和。我的理解正确吗?顺便问一下,有没有办法打印出每个x值的长度为30的每个数组?谢谢。 - venkysmarty
想象一下只取x的第一个值(即sum内部循环的第一次迭代)。假设这个值是0。然后你将计算0-x_d。在NumPy中,这会得到一个数组,其值为[0-x_d[0],0-x_d[1],...]。因此,我们得到了该迭代的长度为30的数组。让我们把它放在脑后,继续进行下一次迭代,这将来自于条目x [1](即x中的第二个条目)。我们重复这个过程,得到[x [1] - x_d [0],x [1] - x_d [1],...]。因此,在sum内部,每次循环都会为该迭代创建一个完整的长度为30的数组。 - ely
如果你想打印中间数组的内容,可以使用 for xi in x: print((abs(xi - x_d) < 0.5))。你甚至可以手动将其中的3个保存到列表中,像这样:test = [(abs(x[0] - x_d) < 0.5), (abs(x[1] - x_d) < 0.5), (abs(x[2] - x_d) < 0.5)],然后尝试 sum(test) 看看会发生什么。 - ely
感谢您的帮助。现在更容易理解这个语句了。 - venkysmarty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接