如何用Pandas统计字典/列表元素在DataFrame指定列的出现次数
解决Pandas中元素出现次数统计的问题
首先,我先帮你定位代码里的问题,再给你更高效的实现方案:
你的代码中的错误点
- 变量名大小写不一致:函数里定义的是
numOfRows,但return时写成了numofRows(小写的o),这会触发NameError - 没必要遍历整行:你只需要对比
TableB的age列,所以lambda里直接判断y == x['age']即可,不用把整行转成列表判断
修正后的可运行代码
先把你的代码调整正确,能得到你想要的结果:
import pandas as pd # 构造示例数据 a = {'age':[22,38,26],'no':[1,2,3]} TableB_data = {'name': ['Braund', 'Cummings', 'Heikkinen', 'Allen'], 'age': [22,38,26,35,41,22,38], 'fare': [7.25, 71.83, 0 , 8.05,7,6.05,6], 'survived?': [False, True, True, False, True, False, True]} TableB = pd.DataFrame(TableB_data) def myfunction(y): # 只针对age列做判断,不用遍历整行 seriesObj = TableB.apply(lambda x: True if y == x['age'] else False, axis=1) numOfRows = len(seriesObj[seriesObj == True].index) return numOfRows # 修正变量名大小写 c = {} c['age'] = a['age'] c['count'] = pd.Series(a['age']).apply(myfunction) # 转成DataFrame更直观 result_df = pd.DataFrame(c) print(result_df)
运行后输出:
age count 0 22 2 1 38 2 2 26 1
更高效的实现方式(推荐)
上面的apply是逐行循环,数据量大时效率很低。Pandas有原生方法可以快速完成这个需求:
方法1:用value_counts + 字典匹配
先统计TableB['age']的所有值出现次数,再匹配a['age']中的元素:
# 统计TableB中age的出现次数,转成字典 age_counts = TableB['age'].value_counts().to_dict() # 构造结果,不存在的元素计数设为0 c = { 'age': a['age'], 'count': [age_counts.get(age, 0) for age in a['age']] } result_df = pd.DataFrame(c) print(result_df)
方法2:用groupby + merge
全程用DataFrame操作,适合更复杂的场景:
# 把a转成DataFrame a_df = pd.DataFrame(a) # 统计TableB的age出现次数 tableb_age_count = TableB.groupby('age').size().reset_index(name='count') # 合并数据,匹配不到的计数填充为0 result_df = a_df[['age']].merge(tableb_age_count, on='age', how='left').fillna(0) # 把计数转成整数类型 result_df['count'] = result_df['count'].astype(int) print(result_df)
这两种方法都比apply高效得多,尤其是当TableB数据量较大时。
针对你的第一个需求(列表元素在DataFrame指定列的出现次数)
比如列表a_list = [22,38,26],要统计每个元素在TableB['age']的出现次数,用方法1最简洁:
a_list = [22,38,26] age_counts = TableB['age'].value_counts().to_dict() counts = [age_counts.get(x, 0) for x in a_list] result = {'elements': a_list, 'count': counts}
内容的提问来源于stack exchange,提问作者Cherry
相关产品推荐
相关产品推荐

