python - Numpy:Row Wise Unique 元素

标签 python numpy scipy

有谁知道如何在矩阵中按行获取唯一元素。例如输入矩阵可能是这样的:

a = [[1,2,1,3,4,1,3],
     [5,5,3,1,5,1,2],
     [1,2,3,4,5,6,7],
     [9,3,8,2,9,8,4],
     [4,6,7,4,2,3,5]]

它应该返回以下内容:

b = rowWiseUnique(a)
=>  b = [[1,2,3,4,0,0,0],
       [5,3,1,2,0,0,0],
       [1,2,3,4,5,6,7],
       [9,3,8,2,4,0,0],
       [4,6,7,2,3,5,0]]

在 numpy 中最有效的方法是什么?我尝试了以下代码,是否有更好、更短的方法?

import numpy as np
def uniqueRowElements(row):
    length = row.shape[0]
    newRow = np.unique(row)
    zerosNumb = length-newRow.shape[0]
    zeros = np.zeros(zerosNumb)
    nR = np.concatenate((newRow,zeros),axis=0)
    return nR    

b = map(uniqueRowElements,a)
b = np.asarray(b)
print b

最佳答案

假设 a 中的值是 float ,您可以使用:

def using_complex(a):
    weight = 1j*np.linspace(0, a.shape[1], a.shape[0], endpoint=False)
    b = a + weight[:, np.newaxis]
    u, ind = np.unique(b, return_index=True)
    b = np.zeros_like(a)
    np.put(b, ind, a.flat[ind])
    return b

In [46]: using_complex(a)
Out[46]: 
array([[1, 2, 0, 3, 4, 0, 0],
       [5, 0, 3, 1, 0, 0, 2],
       [1, 2, 3, 4, 5, 6, 7],
       [9, 3, 8, 2, 0, 0, 4],
       [4, 6, 7, 0, 2, 3, 5]])

请注意,using_complex 不会按与 rowWiseUnique 相同的顺序返回唯一值;根据问题下方的评论,不需要对值进行排序。


最有效的方法可能取决于数组中的行数。 如果行数不太大,使用 mapfor-loop 分别处理每一行的方法是好的, 但是如果有很多行,您可以通过调用 np.unique 来使用 numpy 技巧来处理整个数组,从而做得更好。

诀窍是为每一行添加一个唯一的虚数。 这样,当您调用 np.unique 时,原始数组中的 float 将是 如果它们出现在不同的行中,则被识别为不同的值,但被视为 如果它们出现在同一行中,则为相同的值。

下面,这个技巧在函数 using_complex 中实现。这是比较原始方法 rowWiseUniqueusing_complexsolve 的基准:

In [87]: arr = np.random.randint(10, size=(100000, 10))

In [88]: %timeit rowWiseUnique(arr)
1 loops, best of 3: 1.34 s per loop

In [89]: %timeit solve(arr)
1 loops, best of 3: 1.78 s per loop

In [90]: %timeit using_complex(arr)
1 loops, best of 3: 206 ms per loop

import numpy as np

a = np.array([[1,2,1,3,4,1,3],
     [5,5,3,1,5,1,2],
     [1,2,3,4,5,6,7],
     [9,3,8,2,9,8,4],
     [4,6,7,4,2,3,5]])

def using_complex(a):
    weight = 1j*np.linspace(0, a.shape[1], a.shape[0], endpoint=False)
    b = a + weight[:, np.newaxis]
    u, ind = np.unique(b, return_index=True)
    b = np.zeros_like(a)
    np.put(b, ind, a.flat[ind])
    return b

def rowWiseUnique(a):
    b = map(uniqueRowElements,a)
    b = np.asarray(b)
    return b

def uniqueRowElements(row):
    length = row.shape[0]
    newRow = np.unique(row)
    zerosNumb = length-newRow.shape[0]
    zeros = np.zeros(zerosNumb)
    nR = np.concatenate((newRow,zeros),axis=0)
    return nR    

def solve(arr):
    n = arr.shape[1]
    new_arr = np.empty(arr.shape)
    for i, row in enumerate(arr):
        new_row = np.unique(row)
        new_arr[i] = np.hstack((new_row, np.zeros(n - len(new_row))))
    return new_arr

关于python - Numpy:Row Wise Unique 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26958233/

相关文章:

python - 如何在 Python 中使用 numpy 将 3D 矩阵和 2D 矩阵相乘?

python - 寻找合适的截止值

python - 检测无限递归

python - pypi opencensus-ext-azure 无法正常工作(多次发送相同的数据+不发送logging.info()跟踪)

python - 在python2虚拟环境中安装python3

python - 从多维 numpy 数组中查找和删除

python - numpy 沿第一个轴添加

python - 使用 Scipy 将字典从 Python 保存到 Matlab

python - 为什么 scipy.cluster.hierarchy.linkage 需要一个指标?

python - 在python中使用特征库函数调用C++