统计master_df每行在df1中的出现次数(列顺序无关)
问题:统计无序列组合的出现次数
场景与需求
现有两个DataFrame:
df1 = pd.DataFrame({ 'name': ['Cat', 'Cat', 'Cat', 'David'], 'name2': ['Dog', 'Cat', 'Dog', 'David'], }) master_df = pd.DataFrame({ 'name': ['Dog', 'David'], 'name2': ['Cat', 'David'], })
需要统计master_df中每一行的元素组合(列顺序无关)在df1中的出现次数,期望结果:
final_df = pd.DataFrame({ 'Frequency': ['2', '1'], 'name': ['Dog', 'David'], 'name2': ['Cat', 'David'], })
尝试的代码及问题
原尝试代码:
merged_df = master_df.merge(df1, on=['name', 'name2'], how='left') counts = merged_df.groupby(['name', 'name2']).size().reset_index(name='count') counts
问题出在:原代码是严格按列名顺序匹配,比如master_df中的('Dog','Cat')只会匹配df1里name=Dog且name2=Cat的行,但df1中对应的有效行是name=Cat且name2=Dog,所以无法匹配到,导致统计结果错误。
解决方案
核心思路是:将每行的两个列值转换为排序后的固定顺序组合,这样不管原始列顺序如何,相同元素的组合都会被识别为同一个键,再基于这个键统计频次。
完整代码
import pandas as pd df1 = pd.DataFrame({ 'name': ['Cat', 'Cat', 'Cat', 'David'], 'name2': ['Dog', 'Cat', 'Dog', 'David'], }) master_df = pd.DataFrame({ 'name': ['Dog', 'David'], 'name2': ['Cat', 'David'], }) # 1. 给df1生成排序后的组合键,统一元素顺序 df1['sorted_pair'] = df1.apply(lambda row: tuple(sorted([row['name'], row['name2']])), axis=1) # 统计每个组合的出现次数 pair_counts = df1['sorted_pair'].value_counts().reset_index(name='Frequency') pair_counts.columns = ['sorted_pair', 'Frequency'] # 2. 给master_df生成同样的排序组合键 master_df['sorted_pair'] = master_df.apply(lambda row: tuple(sorted([row['name'], row['name2']])), axis=1) # 匹配频次并清理临时列 final_df = master_df.merge(pair_counts, on='sorted_pair', how='left').drop('sorted_pair', axis=1) # 转换为字符串类型(与期望结果格式一致) final_df['Frequency'] = final_df['Frequency'].astype(str) print(final_df)
代码说明
- 用
apply+sorted把每行的两个值转换成排序后的元组,比如('Dog','Cat')和('Cat','Dog')都会变成('Cat','Dog'),消除列顺序的影响。 - 用
value_counts直接统计df1中每个组合的出现次数,比groupby更简洁。 - 最后通过
merge把频次匹配回master_df,得到目标结果。
内容的提问来源于stack exchange,提问作者Workhorse
相关产品推荐
相关产品推荐

