我有一个像这样的pandas数据框:
from to
a b
b a
c d
c d
d c
我想查找from
和to
组合的计数,无论顺序如何,所以我最终会得到类似的结果:
places count
[a,b] 2
[c,d] 3
我正在努力寻找实现这一目标的有效方法。任何帮助将不胜感激。
答案 0 :(得分:2)
您可以将value_counts()与带有frozenset的压缩列中的元素一起使用。这可能会导致你得到['d','c']。如果你喜欢它们,那么你可以去做:tuple(sorted(i)) for i in zip()
而不是map(frozenset,...)
。与使用groupby-solution相比,似乎有4x
速度提升。 更新:速度比较并不公平,因为这两个解决方案做了不同的事情。
import pandas as pd
data = '''\
from to
a b
b a
c d
c d
d c'''
df = pd.read_csv(pd.compat.StringIO(data), sep='\s+')
out = pd.Series(map(frozenset,zip(df['from'],df['to']))).value_counts().reset_index()
out.rename(columns={'index':'places',0:'count'}, inplace=True)
print(out)
你得到:
places count
0 (d, c) 3
1 (a, b) 2
时间比较:
%timeit pd.Series(map(frozenset,zip(df['from'],df['to']))).value_counts()
%timeit df.apply(np.sort, axis=1).groupby(['from','to']).size()
1000 loops, best of 3: 845 µs per loop
100 loops, best of 3: 3.45 ms per loop
答案 1 :(得分:1)
您可以使用numpy.sort()
和groupby
:
2.5.1
答案 2 :(得分:1)
您可以将collections.Counter
用于O(n)解决方案:
from collections import Counter
c = Counter(map(frozenset, (zip(df['from'], df['to']))))
res = pd.DataFrame.from_dict(c, orient='index').reset_index()
print(res)
# index 0
# 0 (a, b) 2
# 1 (c, d) 3
注意转换为frozenset
是必需的,因为Counter
仅适用于可散列对象。但是,这应该比groupby
解决方案更有效。