如何在df2中新增read_count列统计用户在df1中的匹配次数并排查代码问题?
问题:统计用户在DataFrame列表列中的出现次数
我有两个pandas DataFrame:df1包含文件路径列path和存储用户读取权限列表的read列;df2为所有可能用户的列表。目标是给df2新增read_count列,统计每个用户在df1的read列的列表中出现的总次数。
示例数据
import pandas as pd df1 = pd.DataFrame() df1['path'] = ['C:/pathA', 'C:/pathB', 'C:/pathC', 'C:/pathD'] df1['read'] = [['userA', 'userC', 'userD'], ['userA', 'userB'], ['userB', 'userD'], ['userA', 'userB', 'userC', 'userD']] print(df1)
输出:
path read 0 C:/pathA [userA, userC, userD] 1 C:/pathB [userA, userB] 2 C:/pathC [userB, userD] 3 C:/pathD [userA, userB, userC, userD]
df2定义:
df2 = pd.DataFrame(data=['userA', 'userB', 'userC', 'userD'], columns=['user']) print(df2)
输出:
user 0 userA 1 userB 2 userC 3 userD
预期输出
user read_count 0 userA 3 1 userB 3 2 userC 2 3 userD 3
错误代码及结果
尝试用列表推导式编写代码,但结果全为0:
df2['read_count'] = [sum(all(val in cell for val in row) for cell in df1['read']) for row in df2['user']] print(df2)
输出:
user read_count 0 userA 0 1 userB 0 2 userC 0 3 userD 0
问题分析
你的代码逻辑完全错误:
row是df2中的单个用户(比如userA),但all(val in cell for val in row)会把用户字符串拆成单个字符(比如userA拆成u、s、e、r、A),判断这些字符是否都在cell(df1的read列表)里,这显然不符合需求,且几乎不可能满足,因此求和结果全为0。
正确实现方法
方法1:修正列表推导式
调整逻辑为判断当前用户是否在df1的每个read列表中,再统计次数:
df2['read_count'] = [sum(user in cell for cell in df1['read']) for user in df2['user']]
user in cell直接检查单个用户是否在当前read列表中,sum统计符合条件的行数,即可得到正确计数。
方法2:高效的Pandas原生方法
针对大数据量,推荐用Pandas原生操作提升效率:
# 将df1的read列拆分为每行一个用户 exploded = df1.explode('read') # 统计每个用户的出现次数 counts = exploded['read'].value_counts().reset_index() counts.columns = ['user', 'read_count'] # 与df2合并,确保所有用户被包含(未出现的用户计数为0) df2 = df2.merge(counts, on='user', how='left').fillna(0) # 将计数转为整数类型 df2['read_count'] = df2['read_count'].astype(int)
这种方法更贴合Pandas的操作习惯,数据量越大,效率优势越明显。
内容的提问来源于stack exchange,提问作者gojacketsanddawgs
相关产品推荐
相关产品推荐

