无论顺序如何,列的组合计数

时间:2018-04-07 22:27:59

标签: python pandas

我有一个像这样的pandas数据框:

from    to  
a       b
b       a
c       d
c       d
d       c

我想查找fromto组合的计数,无论顺序如何,所以我最终会得到类似的结果:

places  count
[a,b]   2
[c,d]   3

我正在努力寻找实现这一目标的有效方法。任何帮助将不胜感激。

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解决方案更有效。