簡體   English   中英

用列表的值替換numpy索引數組的值

[英]Replace values of a numpy index array with values of a list

假設你有一個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數組。

PS numpy數組的實際大小是514乘504,列表是8。

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

a[a==2] = 10 #replace all 2's with 10's

numpy中的只讀數組可以寫入:

nArray.flags.writeable = True

這將允許像這樣的賦值操作:

nArray[nArray == 10] = 9999 # replace all 10's with 9999's

真正的問題不是賦值本身,而是可寫標志。

不是逐個替換值,而是可以像這樣重新映射整個數組:

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]]

上述想法歸功於@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

我發現與numpy的功能另一種解決方案place 這里的文件)

在你的例子中使用它:

>>> 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]])

您還可以使用np.choose(idx, vals) ,其中idx是表明其價值指數的陣列vals應放在自己的位置。 但是,索引必須是基於0的。 還要確保idx具有整數數據類型。 所以你只需要這樣做:

np.choose(a.astype(np.int32) - 1, b)

我無法設置標志,或使用掩碼來修改值。 最后我只是制作了一個數組的副本。

a2 = np.copy(a)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM