计算出现次数的其他可能方法是使用 (i) Counter from collections module,(ii) unique from numpy library 和 (iii) groupby + size in @987654331 @。
使用collections.Counter:
from collections import Counter
out = pd.Series(Counter(df['word']))
使用numpy.unique:
import numpy as np
i, c = np.unique(df['word'], return_counts = True)
out = pd.Series(c, index = i)
使用groupby + size:
out = pd.Series(df.index, index=df['word']).groupby(level=0).size()
上述方法中缺少value_counts 的一个非常好的功能是它对计数进行排序。如果对计数进行排序是绝对必要的,那么value_counts 是最好的方法,因为它简单且性能好(尽管它的性能仍略逊于其他方法,尤其是对于非常大的系列)。
基准
(如果对计数进行排序并不重要):
如果我们查看运行时,它取决于存储在 DataFrame 列/系列中的数据。
如果Series是dtype对象,那么对于非常大的Series最快的方法是collections.Counter,但总的来说value_counts很有竞争力。
但是,如果是dtype int,那么最快的方法是numpy.unique:
用于生成绘图的代码:
import perfplot
import numpy as np
import pandas as pd
from collections import Counter
def creator(n, dt='obj'):
s = pd.Series(np.random.randint(2*n, size=n))
return s.astype(str) if dt=='obj' else s
def plot_perfplot(datatype):
perfplot.show(
setup = lambda n: creator(n, datatype),
kernels = [lambda s: s.value_counts(),
lambda s: pd.Series(Counter(s)),
lambda s: pd.Series((ic := np.unique(s, return_counts=True))[1], index = ic[0]),
lambda s: pd.Series(s.index, index=s).groupby(level=0).size()
],
labels = ['value_counts', 'Counter', 'np_unique', 'groupby_size'],
n_range = [2 ** k for k in range(5, 25)],
equality_check = lambda *x: (d:= pd.concat(x, axis=1)).eq(d[0], axis=0).all().all(),
xlabel = '~len(s)',
title = f'dtype {datatype}'
)
plot_perfplot('obj')
plot_perfplot('int')