我正在设置一个二维数组中多个元素的值,但是我的数据有时包含给定索引的多个值。
看起来"later"值总是被赋值的(见下面的例子),但是这种行为是否得到保证,或者是否有可能得到不一致的结果?我如何知道我可以在向量化赋值中以我希望的方式解释"later"?
也就是说,在我的第一个示例中,a
是否一定总是包含4
,而在第二个示例中,它是否会打印values[0]
?
非常简单的例子:
import numpy as np
indices = np.zeros(5,dtype=np.int)
a[indices] = np.arange(5)
a # array([4])
另一个例子
import numpy as np
grid = np.zeros((1000, 800))
# generate indices and values
xs = np.random.randint(0, grid.shape[0], 100)
ys = np.random.randint(0, grid.shape[1], 100)
values = np.random.rand(100)
# make sure we have a duplicate index
print values[0], values[5]
xs[0] = xs[5]
ys[0] = ys[5]
grid[xs, ys] = values
print "output value is", grid[xs[0], ys[0]]
# always prints value of values[5]
5条答案
按热度按时间3npbholx1#
在NumPy 1.9和更高版本中,这通常不会得到很好的定义。
当前实现将遍历所有(广播的)花式索引(和赋值数组)同时使用单独的迭代器,这些迭代器都使用C序,换句话说,目前,是的,你可以,因为你可能想知道它更准确,如果你在处理这些事情的NumPy中比较
mapping.c
,你会看到它使用PyArray_ITER_NEXT
,也就是documented是C阶的。对于未来,我会用不同的方式来描述。我认为使用较新的迭代器来迭代所有索引+赋值数组会很好。如果这样做了,那么顺序可以保持开放,以便迭代器决定最快的方式。如果你保持它对迭代器开放,很难说会发生什么。但是你不能确定你的例子是否有效(可能是1-D的情况,你仍然可以,但是...)。
所以,据我所知,它目前的工作,但它是没有文件(据我所知),所以如果你真的认为这应该得到保证,你需要游说它,最好写一些测试,以确保它可以得到保证.因为至少我忍不住要说:如果它使事情更快,那么就没有理由确保C阶,但当然可能在某个地方隐藏着一个很好的理由...
真实的的问题是:你到底为什么要那个?)
e7arh2l62#
我知道这个问题已经得到了令人满意的回答,但我想提一下,它在Tentative Numpy Tutorial中的“last value”(可能是非正式的)是在使用索引数组进行索引下记录的:
但是,当索引列表包含重复时,赋值将执行多次,并留下最后一个值:
这很合理,但是如果你想使用Python的+=结构,要小心,因为它可能不会做你所期望的事情:
即使0在索引列表中出现了两次,第0个元素也只递增一次,这是因为Python要求
a+=1
等价于a=a+1
。k75qkfdt3#
我不是直接回答你的问题,我只是想指出一点,即使你可以依赖于这种行为是一致的,你最好不要。
考虑:
此时,假设
a.sum()
为a
的前一个和+x.sum()
是否合理?在您的示例中,当使用重复索引为数组赋值时,结果是直观的:对同一索引的赋值会发生多次,因此只有最后一次赋值会"保留"(它会覆盖以前的赋值)。
但是这个例子中的情况不是这样的,它不再是直观的,如果是直观的,就地加法就会发生多次,因为加法本质上是累积的。
所以,换句话说,你正冒着陷入这个陷阱的风险:
所以,引用@seberg的话:
真正的问题是:你到底为什么要那个?)
acruukt94#
我找到了一种方法,用with numpy来做这个操作,这显然不是最佳的,但它比循环(用python for循环)更快
与:麻木。双计数
这是不正确的,但是:
味道不错!
xfb7svmp5#
时间在变,应该给出最新的答案。