如何获取二维数组中指定列的唯一行索引

时间:2014-10-24 00:34:46

标签: python numpy

如果我有像这样的numpy索引......

import numpy as np

a = np.array([
    [0, 0],
    [0, 1],
    [1, 0],
    [1, 1],
])

如何找到一个或多个指定列中的值唯一的行的索引?我的意思是......如果我将列指定为“掩码”,我如何使用该列作为掩码找到唯一的行?例如,如果我想......

相对于列0的唯一行(第0列是掩码)。我想要这样的回报......

[[0,1],[2,3]]

因为如果您使用第0列作为唯一性的标准,则行0和1将位于相同的“唯一组”中,而第2行和第3行将位于另一个“唯一组”中,因为它们在列中具有相同的值0

如果我想要关于第1列的行(第1列现在是掩码),我希望得到这样的输出....

[[0,2],[1,3]]

因为使用第1列作为唯一性标准会导致第0行和第2行以及第1行和第3行在它们各自的独立组中,因为它们在第1列中具有相同的值

我还希望能够获得关于多个列的唯一行所以如果我想要关于列0和1的唯一行(现在列0和1都是掩码)我想要这个返回....

[[0],[1],[2],[3]]

因为当您使用两列作为唯一性标准时,有四个唯一的行。

在numpy中有一种简单的方法吗?感谢。

4 个答案:

答案 0 :(得分:1)

这是一个自定义解决方案,当然不会非常高效,因为它会进行大量复制并直接遍历矩阵:

def groupby(a, key_columns):
    from collections import defaultdict
    groups = defaultdict(list)
    for i, row in enumerate(a):
        groups[tuple(row[c] for c in key_columns)].append(i)
    return groups.values()

这假定key_columns是一个列表或元组,其中包含您有兴趣进行分组的相应列。您还可以进行一些参数检查并将单个索引提升为单个列表。

运行以下示例会产生此输出:

>>> groupby(a, [0])
[[0, 1], [2, 3]]
>>> groupby(a, [1])
[[0, 2], [1, 3]]

它也适用于您问过的多个键列:

>>> groupby(a, [0, 1])
[[1], [2], [0], [3]]

请注意,在这种情况下,由于使用了defaultdict,因此无法保证值的顺序。您可以对结果值进行排序,也可以使用collections.OrderedDict,具体取决于您计划如何使用二级索引。

答案 1 :(得分:1)

尝试使用itertools.groupby

from itertools import groupby

data = [1,3,2,3,4,1,5,2,6,3,4]
data = [(x, k) for k, x in enumerate(data)]
data = sorted(data)

groups = []
for k, g in groupby(data, lambda x:x[0]):
    groups.append([x[1] for x in g])

print(groups)

输出

[[0, 5], [2, 7], [1, 3, 9], [4, 10], [6], [8]]

答案 2 :(得分:0)

一种可能的方法,使用循环:

import numpy

a = numpy.array([
    [0, 0],
    [0, 1],
    [1, 0],
    [1, 1],
])


un = numpy.unique(a)

results = []

# could be a list comprehension
for val in un:  

    # zero-th column, change as needed:   
    indices = a[:,0] == val  

    results.append(numpy.argwhere(indices).flatten())

result = numpy.array(results)

print result

根据您的需求和最终目标,您可以使用Pandas库。

它有一个groupby方法可以像这样使用:

import pandas
import numpy as np

a = np.array([
    [0, 0],
    [0, 1],
    [1, 0],
    [1, 1],
])


df = pandas.DataFrame(a).groupby([0])  # zero-th column, change as needed

for key, group in df:
    print group.values

请注意,这会返回实际值,而不是索引。

答案 3 :(得分:0)

numpy_indexed包(免责声明:我是它的作者)为这类问题提供了一个完全矢量化的解决方案:

import numpy_indexed as npi
# entire rows of a determine uniqueness
npi.unique(a)
# only second column determines uniqueness
npi.unique(a[:, 1])

还有更多的列类型。