如何在Pandas中基于指定列匹配与固定值计数创建新列?
问题描述
现有如下DataFrame:
col_1 col_2 col_3 6 A 1 2 A 1 5 B 1 3 C 1 5 C 2 3 B 2 6 A 1 6 A 0 2 B 3 2 C 3 5 A 3 5 B 1
需要新增一列col_new,规则是:统计与当前行col_1、col_2值相同,但排除当前行且col_3值为1的行数(无论当前行col_3实际值是否为1)。期望输出如下:
col_1 col_2 col_3 col_new 6 A 1 1 2 A 1 0 5 B 1 1 3 C 1 0 5 C 2 0 3 B 2 0 6 A 1 1 6 A 0 1 # 即使当前行col_3为0 2 B 3 0 2 C 3 0 5 A 3 0 5 B 1 1
尝试的代码存在问题:
df['col_new'] = df[df['col_3' == 1]].groupby(['col_1', 'col_2'])['col_2'].transform('count').sub(1)
该代码仅在col_3值为1的行结果正确,col_3值不为1的行(如第8行)会出现NaN。
解决方案
方法1:映射表+行遍历(简单直观)
- 先统计每个
(col_1, col_2)组合下,col_3=1的总行数:
count_map = df[df['col_3'] == 1].groupby(['col_1', 'col_2']).size().to_dict()
- 为每行计算
col_new:如果当前行col_3=1,则总数减1(排除自身);否则直接用总数:
df['col_new'] = df.apply( lambda row: count_map.get((row['col_1'], row['col_2']), 0) - (1 if row['col_3'] == 1 else 0), axis=1 )
方法2:向量化实现(高效,适合大数据集)
避免行遍历,用merge和条件判断提升性能:
# 计算每个分组的col_3=1的总数 count_df = df[df['col_3'] == 1].groupby(['col_1', 'col_2'], as_index=False).size().rename(columns={'size': 'total_count'}) # 合并到原DataFrame,无匹配的分组填充0 df = df.merge(count_df, on=['col_1', 'col_2'], how='left').fillna(0) # 计算col_new:当前行col_3=1则总数减1,否则直接用总数 df['col_new'] = df['total_count'] - df['col_3'].eq(1).astype(int) # 可选:删除临时列total_count df = df.drop('total_count', axis=1)
问题根源说明
原代码存在两个问题:
- 语法错误:
df['col_3' == 1]括号位置错误,正确应为df[df['col_3'] == 1] - 逻辑缺陷:仅筛选
col_3=1的行做分组,导致其他行没有匹配结果,出现NaN。正确思路是先统计全量符合条件的总数,再根据当前行是否属于统计范围调整数值。
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

