用列表的值替换 numpy 索引数组的值 [英] Replace values of a numpy index array with values of a list

查看:32
本文介绍了用列表的值替换 numpy 索引数组的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<预><代码>>>>a = np.array([1,2,2,1]).reshape(2,2)>>>一个数组([[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):如果 x==1:x[...]=x=0elif x==2:x[...]=x=10

给我一​​个错误:

ValueError: 赋值目标是只读的

我想那是因为我无法真正写入 numpy 数组.

附言numpy 数组的实际大小为 514 x 504,列表的实际大小为 8.

解决方案

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

将 numpy 导入为 npa = np.array([1,2,2,1]).reshape(2,2)# 调色板必须按排序顺序给出调色板 = [1, 2]# key 给出了您希望调色板映射到的新值.键 = np.array([0, 10])index = np.digitize(a.ravel(), 调色板, right=True)打印(键[索引].reshape(a.shape))

收益

[[ 0 10][10 0]]

<小时>

上述想法归功于@JoshAdel.它比我原来的答案要快得多:

将 numpy 导入为 np随机导入调色板 = np.arange(8)键 = 调色板**2a = np.array([random.choice(palette) for i in range(514*504)]).reshape(514,504)def using_unique():调色板,索引 = np.unique(a, return_inverse=True)返回键[索引].reshape(a.shape)def using_digitize():index = np.digitize(a.ravel(), 调色板, right=True)返回键[索引].reshape(a.shape)如果 __name__ == '__main__':断言 np.allclose(using_unique(), using_digitize())

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

在 [107]: %timeit using_unique()10 个循环,最好的 3 个:每个循环 35.6 毫秒在 [112]: %timeit using_digitize()100 个循环,最好的 3 个:每个循环 5.14 毫秒

Suppose you have a numpy array and a list:

>>> a = np.array([1,2,2,1]).reshape(2,2)
>>> a
array([[1, 2],
       [2, 1]])
>>> b = [0, 10]

I'd like to replace values in an array, so that 1 is replaced by 0, and 2 by 10.

I found a similar problem here - http://mail.python.org/pipermail//tutor/2011-September/085392.html

But using this solution:

for x in np.nditer(a):
    if x==1:
        x[...]=x=0
    elif x==2:
        x[...]=x=10

Throws me an error:

ValueError: assignment destination is read-only

I guess that's because I can't really write into a numpy array.

P.S. The actual size of the numpy array is 514 by 504 and of the list is 8.

解决方案

Instead of replacing the values one by one, it is possible to remap the entire array like this:

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

yields

[[ 0 10]
 [10  0]]


Credit for the above idea goes to @JoshAdel. It is significantly faster than my original answer:

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

I benchmarked the two versions this way:

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 索引数组的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆