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