用列表的值替换numpy索引数组的值

abu*_*dis 19 python indexing numpy

假设你有一个numpy数组和一个列表:

>>> a = np.array([1,2,2,1]).reshape(2,2)
>>> a
array([[1, 2],
       [2, 1]])
>>> b = [0, 10]
Run Code Online (Sandbox Code Playgroud)

我想替换数组中的值,以便将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
Run Code Online (Sandbox Code Playgroud)

给我一个错误:

ValueError: assignment destination is read-only
Run Code Online (Sandbox Code Playgroud)

我想这是因为我无法写入一个numpy数组.

PS numpy数组的实际大小是514乘504,列表是8.

ale*_*dan 30

好吧,我想你需要的是什么

a[a==2] = 10 #replace all 2's with 10's
Run Code Online (Sandbox Code Playgroud)

  • 当我这样做时,我得到"分配目的地是只读的",你知道为什么会这样吗? (4认同)

Dor*_*scu 22

numpy中的只读数组可以写入:

nArray.flags.writeable = True
Run Code Online (Sandbox Code Playgroud)

这将允许像这样的赋值操作:

nArray[nArray == 10] = 9999 # replace all 10's with 9999's
Run Code Online (Sandbox Code Playgroud)

真正的问题不是赋值本身,而是可写标志.


unu*_*tbu 19

不是逐个替换值,而是可以像这样重新映射整个数组:

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))
Run Code Online (Sandbox Code Playgroud)

产量

[[ 0 10]
 [10  0]]
Run Code Online (Sandbox Code Playgroud)

上述想法归功于@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())
Run Code Online (Sandbox Code Playgroud)

我用这种方式对两个版本进行了基准测试

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
Run Code Online (Sandbox Code Playgroud)