根据规则替换多维numpy数组的元素

时间:2016-03-26 05:26:04

标签: python arrays numpy multidimensional-array replace

我们说我们有一个numpy数组:

import numpy as np
arr = np.array([[ 5,  9],[14, 23],[26,  4],[ 5, 26]])

我想用每个元素的出现次数替换

 unique0, counts0= np.unique(arr.flatten(), return_counts=True)
 print (unique0, counts0)
  

(数组([4,5,9,14,23,26]),数组([1,2,1,1,1,2]))

所以4应该被1,5替换2等取代:

  

[[2,1],[1,1],[2,1],[2,2]]

有没有办法在numpy中实现这个目标?

2 个答案:

答案 0 :(得分:3)

将另一个可选参数return_inversenp.unique一起使用,根据其唯一性标记所有元素,然后将这些元素与计数一起映射,以便为我们提供所需的输出,如下所示 -

_, idx, counts0 = np.unique(arr, return_counts=True,return_inverse=True)
out = counts0[idx].reshape(arr.shape)

示例运行 -

In [100]: arr
Out[100]: 
array([[ 5,  9],
       [14, 23],
       [26,  4],
       [ 5, 26]])

In [101]: _, idx, counts0 = np.unique(arr, return_counts=True,return_inverse=True)

In [102]: counts0[idx].reshape(arr.shape)
Out[102]: 
array([[2, 1],
       [1, 1],
       [2, 1],
       [2, 2]])

答案 1 :(得分:1)

这是另一种解决方案,因为@Divakar的答案在版本< 1.9中不起作用:

 In [1]: import numpy as np

 In [2]: arr = np.array([[ 5,  9],[14, 23],[26,  4],[ 5, 26]])

 In [3]: np.bincount(arr.flatten())[arr]
 Out[3]: 
 array([[2, 1],
        [1, 1],
        [2, 1],
        [2, 2]])

测试速度(10000个随机整数):

def replace_unique(arr):
    _, idx, counts0 = np.unique(arr,return_counts=True,return_inverse=True)
    return counts0[idx].reshape(arr.shape)

def replace_bincount(arr):
    return np.bincount(arr.flatten())[arr]

arr = np.random.random_integers(30,size=[10000,2])


%timeit -n 1000 replace_bincount(arr)
# 1000 loops, best of 3: 68.3 µs per loop
%timeit -n 1000 replace_unique(arr)
# 1000 loops, best of 3: 922 µs per loop

所以bincount方法比unique方法快〜14倍。