如何使用Pandas使用两列计算两个项目的频率

时间:2015-12-20 11:12:04

标签: python pandas

我有一个非常大的文件(5GB),我需要使用两列来计算出现次数

     a   b   c   d   e
0    2   3   1   5   4
1    2   3   2   5   4
2    1   3   2   5   4
3    2   4   1   5   3
4    2   4   1   5   3
显然我必须找到

(2,3):2
(1,3):1
(2,4):2

我怎样才能以非常快的方式做到这一点。

我用过:

df.groupby(['a','b']).count().to_dict() 

假设最终结果是

a b freq
2 3 2
1 3 1
2 4 2

1 个答案:

答案 0 :(得分:2)

问题的第一个版本的方法 - 字典作为结果

如果您有高频率,即ab的几种组合,则最终字典会很小。如果你有许多不同的组合,你将需要大量的RAM。

如果你有低频率和足够的RAM,看起来你的方法很好。

5e6行的一些时间和0到19之间的数字:

>>> df = pd.DataFrame(np.random.randint(0, 19, size=(5000000, 5)), columns=list('abcde'))
>>> df.shape
(5000000, 5)

%timeit df.groupby(['a','b']).count().to_dict() 
1 loops, best of 3: 552 ms per loop

%timeit  df.groupby(['a','b']).size()
1 loops, best of 3: 619 ms per loop

%timeit  df.groupby(['a','b']).count()
1 loops, best of 3: 588 ms per loop

使用不同的整数范围,这里最多sys.maxsize(9223372036854775807),会大大改变时间:

import sys
df = pd.DataFrame(np.random.randint(0, high=sys.maxsize, size=(5000000, 5)), 
                  columns=list('abcde'))


%timeit df.groupby(['a','b']).count().to_dict() 
1 loops, best of 3: 41.3 s per loop

%timeit  df.groupby(['a','b']).size()
1 loops, best of 3: 11.4 s per loop

%timeit  df.groupby(['a','b']).count()
1 loops, best of 3: 12.9 s per loop`

更新问题的解决方案

df2 = df.drop(list('cd'), axis=1)
df2.rename(columns={'e': 'feq'}, inplace=True)
g = df2.groupby(['a','b']).count()
g.reset_index(inplace=True) 
print(g)

   a  b  feq
0  1  3    1
1  2  3    2
2  2  4    2

但速度并不快。

对于范围0到19:

%%timeit
df2 = df.drop(list('cd'), axis=1)
df2.rename(columns={'e': 'feq'}, inplace=True)
g = df2.groupby(['a','b']).count()
g.reset_index(inplace=True) 

1 loops, best of 3: 564 ms per loop

范围0到sys.maxsize

%%timeit
df2 = df.drop(list('cd'), axis=1)
df2.rename(columns={'e': 'feq'}, inplace=True)
g = df2.groupby(['a','b']).count()
g.reset_index(inplace=True) 
1 loops, best of 3: 10.2 s per loop