我有一个非常大的文件(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
答案 0 :(得分:2)
如果您有高频率,即a
和b
的几种组合,则最终字典会很小。如果你有许多不同的组合,你将需要大量的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