比较numpy数组中的行

3 投票
2 回答
3950 浏览
提问于 2025-04-16 05:23

我有一个二维的numpy布尔数组,我想知道我的数据集中有多少个独特的行,以及每一行出现的频率。我唯一能想到的解决办法是把整个数据集转换成字符串,然后进行比较,但我相信一定有更好的方法。希望能得到一些帮助。

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

我喜欢这个有帮助的解决方案:

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

这个方法非常快。我的唯一担心是:有没有办法用数组来实现同样的功能,而不是用 dict() 呢?我在打印唯一字典的时候遇到了麻烦,想要不显示字典的格式。谢谢,Giuseppe

2

可以看看 numpy.uniquenumpy.bincount

例如:

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

编辑:抱歉,我误解了你的问题……

获取唯一行的一种方法是把数据看作一个结构化数组……

在你的情况下,你有一个二维的布尔数组。所以也许可以这样做?

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风格”的做法要快……(我本来以为会相反!不过像你最开始的例子那样把行转换成字符串是比较慢的。你肯定想比较元组,而不是字符串)。

撰写回答