假设你有一个numpy数组和一个列表:
>>> a = np.array([1,2,2,1]).reshape(2,2)
>>> a
array([[1, 2],
[2, 1]])
>>> b = [0, 10]
我想替换数组中的值,以便将1替换为0,将2替换为10.
我在这里发现了类似的问题 - http://mail.python.org/pipermail//tutor/2011-September/085392.html
但是使用这个解决方案:
for x in np.nditer(a):
if x==1:
x[...]=x=0
elif x==2:
x[...]=x=10
给我一个错误:
ValueError: assignment destination is read-only
我想这是因为我无法写入一个numpy数组。
P.S。 numpy数组的实际大小是514乘504,列表是8.
答案 0 :(得分:30)
好吧,我想你需要的是
a[a==2] = 10 #replace all 2's with 10's
答案 1 :(得分:22)
numpy中的只读数组可以写成:
nArray.flags.writeable = True
这将允许像这样的赋值操作:
nArray[nArray == 10] = 9999 # replace all 10's with 9999's
真正的问题不是赋值本身,而是可写标记。
答案 2 :(得分:18)
不是逐个替换值,而是可以像这样重新映射整个数组:
import numpy as np
a = np.array([1,2,2,1]).reshape(2,2)
# palette must be given in sorted order
palette = [1, 2]
# key gives the new values you wish palette to be mapped to.
key = np.array([0, 10])
index = np.digitize(a.ravel(), palette, right=True)
print(key[index].reshape(a.shape))
产量
[[ 0 10]
[10 0]]
Credit for the above idea goes to @JoshAdel。它明显快于我原来的答案:
import numpy as np
import random
palette = np.arange(8)
key = palette**2
a = np.array([random.choice(palette) for i in range(514*504)]).reshape(514,504)
def using_unique():
palette, index = np.unique(a, return_inverse=True)
return key[index].reshape(a.shape)
def using_digitize():
index = np.digitize(a.ravel(), palette, right=True)
return key[index].reshape(a.shape)
if __name__ == '__main__':
assert np.allclose(using_unique(), using_digitize())
我用这种方式对这两个版本进行了基准测试:
In [107]: %timeit using_unique()
10 loops, best of 3: 35.6 ms per loop
In [112]: %timeit using_digitize()
100 loops, best of 3: 5.14 ms per loop
答案 3 :(得分:0)
我找到了numpy函数place
的另一个解决方案。 (文件here)
在您的示例中使用它:
>>> a = np.array([1,2,2,1]).reshape(2,2)
>>> a
array([[1, 2],
[2, 1]])
>>> np.place(a, a==1, 0)
>>> np.place(a, a==2, 10)
>>> a
array([[ 0, 10],
[10, 0]])
答案 4 :(得分:0)
您还可以使用np.choose(idx, vals)
,其中idx
是一系列索引,用于指示应将vals
的值放在哪个位置。但是,索引必须是基于0的。还要确保idx
具有整数数据类型。所以你只需要这样做:
np.choose(a.astype(np.int32) - 1, b)
答案 5 :(得分:0)
我无法设置标志或使用掩码修改值。最后,我只是复制了一个数组。
a2 = np.copy(a)