如何高效获取Pandas Series元素按首次出现顺序的频次列表
嘿,这个性能问题我太熟了!处理百万级数据的时候,循环遍历绝对是大忌,咱们直接用Pandas内置的高效方法来解决:
最优解决方案:groupby 配合 sort=False
直接用groupby并设置sort=False,它会严格保留ID首次出现的顺序,然后用size()统计每组的行数,整个过程只需要一次遍历,效率拉满:
import pandas as pd # 构造你的示例数据 df = pd.DataFrame({'ID': [1,2,3,3,3,2,1,5,2,3,1,2,4,3]}) # 按首次出现顺序统计频次,转成列表 group_size = df.groupby('ID', sort=False).size().tolist() print(group_size) # 输出: [3,4,5,1,1],完全符合你的期望
为什么之前的方法慢到离谱?
你原来的循环写法:
group_list = df.ID.unique().tolist() group_size = [] for i in group_list: group_size.append(df.ID.value_counts()[i])
问题出在每次循环都要重新计算整个ID列的频次!比如如果有10万个唯一ID,相当于要对500万行数据重复统计10万次,时间复杂度直接飙升到O(n*m),完全没必要。
为什么value_counts(sort=False)不对?
value_counts(sort=False)的排序逻辑是按ID值的自然顺序(比如数字从小到大、字符串按字典序),而不是按ID在原数据中首次出现的顺序。比如如果你的ID是['b','a','c','b'],value_counts(sort=False)会按a,b,c排序,而不是原数据的b,a,c顺序,这就不符合你的需求了。
另一个高效备选:pd.factorize
如果你想换个思路,pd.factorize可以把ID转换成首次出现顺序的编码,再统计编码的频次:
codes, uniques = pd.factorize(df['ID']) counts = pd.Series(codes).value_counts(sort=False).tolist() print(counts) # 同样得到: [3,4,5,1,1]
这个方法的效率和groupby差不多,也是O(n)的时间复杂度,适合需要同时获取唯一值列表和对应频次的场景。
内容的提问来源于stack exchange,提问作者CuriousGeorge
相关产品推荐
相关产品推荐

