比较numpy数组中的行

时间:2010-10-13 01:14:20

标签: python numpy scipy

我有一个2d numpy bool数组,我想知道我的数据集包含多少个唯一行以及每行的频率。解决这个问题的唯一方法是将我的整个数据集转换为字符串,然后进行比较,但肯定有更好的方法来做到这一点。任何帮助表示赞赏。

def getUniqueHaplotypes(self,data):
nHap=data.shape[0]
unique=dict() 
for i in range(nHap):
    s = "".join([str(j) for j in data[i]])
    if unique.has_key(s):
        unique[s]+=1
    else:
        unique[s] = 1

return unique

2 个答案:

答案 0 :(得分:2)

查看numpy.uniquenumpy.bincount

E.g。

import numpy as np
x = (np.random.random(100) * 5).astype(np.int)
unique_vals, indicies = np.unique(x, return_inverse=True)
counts = np.bincount(indicies)

print unique_vals, counts

编辑:对不起,我误解了你的问题......

获取唯一行的一种方法是将事物视为结构化数组......

在你的情况下,你有一个二维的bool数组。也许是这样的?

import numpy as np
numrows, numcols = 10,3
x = np.random.random((numrows, numcols)) > 0.5
x = x.view(','.join(numcols * ['i1'])) # <- View the rows as a 1D structured array...

unique_vals, indicies = np.unique(x, return_inverse=True)
counts = np.bincount(indicies)

print unique_vals, counts

当然,你最初这样做的方式并没有什么问题......只是为了显示一种稍微更清晰的方式来编写原始函数(使用元组,就像Justin建议的那样):

def unique_rows(data):
    unique = dict()
    for row in data:
        row = tuple(row)
        if row in unique:
            unique[row] += 1
        else:
            unique[row] = 1
    return unique

我们可以更进一步使用defaultdict:

from collections import defaultdict
def unique_rows(data):
    unique = defaultdict(int)
    for row in data:
        unique[tuple(row)] += 1
    return unique

碰巧,这些选项中的任何一个似乎都比“numpy-thonic”这样做的方式更快......(我猜对了!正如你在原始例子中所做的那样将行转换为字符串是但是很慢。你肯定想比较元组而不是字符串)。

答案 1 :(得分:0)

我喜欢有用的解决方案:

def unique_rows(data):
    unique = dict()
    for row in data:
        row = tuple(row)
        if row in unique:
            unique[row] += 1
        else:
            unique[row] = 1
    return unique

非常快。我唯一担心的是:使用unique作为数组而不是dict()?可以执行相同的操作我在没有字典格式的情况下打印唯一字典时遇到了麻烦。 谢谢Giuseppe