Numpy数组切片与for循环结果

时间:2013-03-10 00:18:57

标签: python arrays numpy slice

考虑一个由不同密度的壳组成的球体 我有两个数组,一个用于每个shell的外半径(rad[]),另一个用于每个shell的密度(den[])。我想计算出一个给定半径的质量,称为mass[]

以下for循环方法通过首先找到最里面的壳的质量(内半径为零,因此它是一个球体),然后每个后续壳的质量 - 添加到前一个(求和)来实现所需的结果)质量:

mass = numpy.zeros(len(rad))                                   # create array
mass[0] = den[0]**(rad[0]**3)                                  # find inner sphere mass
for i in range(1,len(mass)):
    mass[i] = mass[i-1] + den[i]*(rad[i]**3 - rad[i-1]**3)     # Find mass out to shell i

注意:我只需要缩放,所以我不担心pi的因素。

有人可以解释为什么以下切片结果不会达到相同的效果吗?

mass = numpy.zeros(len(rad))
mass[0]  = den[0]*(rad[0]**3)
mass[1:] = mass[0:-1] + den[1:]*(rad[1:]**3-rad[0:-1]**3)

1 个答案:

答案 0 :(得分:3)

原因是numpy数组中的所有元素都将同时计算。第二行中的数组mass[0:-1]将被评估为den[0]*(rad[0]**3),后面只有零。 (一旦计算了行,mass[1]将不再为零的事实是无关紧要的 - 那时为时已晚。)

你注意到了这个例子:

test = numpy.linspace(1,10,num=10)
test[1:] += test[0:-1]
# [  1.   3.   6.  10.  15.  21.  28.  36.  45.  55.]

的工作方式不同,好像加法确实是迭代发生的。您的示例中的差异是向右侧添加了一个值 - 该添加使其成为内存中的新数组(x + yx不是同一个数组),这样{{1}不再将其视为自我添加。见这个例子

numpy

如果你想做你的for循环的矢量化版本,你可以这样做:

test = numpy.linspace(1,10,num=10)
test[1:] += test[0:-1] + 0
# [  1.   3.   5.   7.   9.  11.  13.  15.  17.  19.]