考虑一个由不同密度的壳组成的球体
我有两个数组,一个用于每个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)
答案 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 + y
与x
不是同一个数组),这样{{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.]