嗨,我目前正在执行以下操作,以在几个熊猫系列中找到所有唯一的物品:
vscode.uri("c:\\some\\path")
由于真实数据很大,有什么方法可以加快速度。
谢谢。
反馈意见
代码:
In [44]: data = [Series([1,2,7,4]), Series([2,5,3,1]), Series([3, 2, 4])]
In [45]: counts = Counter(chain.from_iterable(data))
In [46]: unique_occurrences = [item for item, count in counts.items() if count == 1]
In [47]: unique_occurrences
Out[47]: [7, 5]
Spyder会话:
def uniq_0(data): # Original
counts = Counter(chain.from_iterable(data))
return [item for item, count in counts.items() if count == 1]
def uniq_1(data): # Divakar #1
a = np.concatenate(data)
unq,c = np.unique(a, return_counts=1)
return unq[c==1]
def uniq_2(data): # Divakar #2
a = np.concatenate(data)
return np.flatnonzero(np.bincount(a)==1)
def uniq_3(data): # Divakar #3
counts = Counter(chain.from_iterable(data))
k = np.array(list(counts.keys()))
v = np.array(list(counts.values()))
return k[v==1]
def uniq_4(data): # Divakar #4
L = max([i.max() for i in data])+1
return np.flatnonzero(np.sum([np.bincount(i,minlength=L)
for i in data],axis=0)==1)
def uniq_5(data): # Divakar #5
L = max([i.max() for i in data])+1
sums = np.zeros(L,dtype=int)
for i in data:
sums += np.bincount(i,minlength=L)
return np.flatnonzero(sums==1)
def uniq_6(data): # Erfan
v = pd.concat(data).value_counts()
return v.index[v == 1]
if __name__ == '__main__':
data = [Series([1,2,7,4]), Series([2,5,3,1]), Series([3, 2, 4])]
funcs = [uniq_0, uniq_1, uniq_2, uniq_3, uniq_4, uniq_5, uniq_6]
answers = [f(data) for f in funcs]
golden = set(answers[0])
check = [set(a) == golden for a in answers]
for n, a in enumerate(answers):
if set(a) != golden:
print(f' Error with uniq_{n}(data)')
else:
print(f' Confirmed uniq_{n}(data) == golden')
评论
非常感谢您。我的实际数据较大,但无法在这台笔记本电脑上使用,但是我觉得我现在有足够的选择来做到这一点。 再次感谢!
答案 0 :(得分:3)
方法1
这是一个基于NumPy的数组-
a = np.concatenate(data)
unq,c = np.unique(a, return_counts=1)
out = unq[c==1]
方法2(用于正整数数据)
对于正整数数据,我们可以使用np.bincount
直接从out
获得a
-
out = np.flatnonzero(np.bincount(a)==1) # a from app#1
方法3
如果我们要使用counts
,在处理大量序列时可能更喜欢,因为在这种情况下串联可能会更慢-
k = np.array(list(counts.keys()))
v = np.array(list(counts.values()))
out = k[v==1]
方法4(用于正整数数据)
由于大量的序列包含正整数,因此我们可以在每个序列上使用bincount
,从而避免串联-
L = max([i.max() for i in data])+1
out = np.flatnonzero(np.sum([np.bincount(i,minlength=L) for i in data],axis=0)==1)
方法5(用于正整数数据)
可以像这样进一步改善内存效率-
L = max([i.max() for i in data])+1
sums = np.zeros(L,dtype=int)
for i in data:
sums += np.bincount(i,minlength=L)
out = np.flatnonzero(sums==1)
答案 1 :(得分:2)
我们可以结合使用pd.concat
和value_counts
并应用布尔索引:
v = pd.concat(data).value_counts()
v.index[v == 1].to_numpy()
哪个产量
array([7, 5], dtype=int64)
注意
如果您的熊猫版本为<0.24.0,请改用:
v.index[v == 1].values
了解更多here。