You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中分组统计跨列唯一序列计数及缺失值处理问题

Pandas含NaN序列的计数问题解决

问题背景

有一个包含x、y1、y2、y3、y4列的Pandas DataFrame A,需要统计每个x对应的{y1,y2,y3,y4}唯一序列的出现次数。目前通过循环拼接子数据、去重得到了包含各x唯一序列的DataFrame B,但使用apply统计次数时,含NaN的序列count值为0——因为NaN与任何值(包括自身)比较都会返回False,无法满足将缺失值视为唯一值的需求。

现有问题代码

B = pd.DataFrame()
for x_temp in A['x'].unique():
    B = pd.concat([B, A[A['x'] == x_temp][['x','y1','y2','y3','y4']]])
B = B.drop_duplicates().sort_values(by=['x','y1','y2','y3','y4'])
del x_temp 

B['count'] = A.apply(lambda row: (A['y1'] == row['y1']) & (A['y2'] == row['y2']) & (A['y3'] == row['y3']) & (A['y4'] == row['y4']), axis=1).sum()

示例数据

import pandas as pd
import numpy as np

A = pd.DataFrame({'x':['1','1','1','1','2','2','2','2','2','1'],
                   'y1':['1','2','2',np.nan,'2',np.nan,'2','2','2','1'],
                   'y2':['2','1','2','2',np.nan,np.nan,'2','2','1','2'],
                   'y3':['1','1',np.nan,'2',np.nan,'2',np.nan,np.nan,'1','1'],
                   'y4':['2','2','2',np.nan,np.nan,'1','2','2','2','2']})

解决方案

方法一:直接分组统计(推荐)

利用Pandas的groupby功能,设置dropna=False将NaN视为独立分组键,直接得到包含唯一序列和对应计数的结果:

# 按x和y1-y4分组,统计每个序列的出现次数
B = A.groupby(['x', 'y1', 'y2', 'y3', 'y4'], dropna=False).size().reset_index(name='count')
# 按需求排序
B = B.sort_values(by=['x','y1','y2','y3','y4'])

方法二:基于原有B逻辑的改进版

如果需要保留原有生成B的逻辑,可以先得到唯一序列的B,再通过合并分组统计结果添加count列:

# 生成唯一序列的B(简化原有循环逻辑)
B = A.drop_duplicates(subset=['x','y1','y2','y3','y4']).sort_values(by=['x','y1','y2','y3','y4'])
# 统计每个序列的次数
count_df = A.groupby(['x', 'y1', 'y2', 'y3', 'y4'], dropna=False).size().reset_index(name='count')
# 合并count到B
B = B.merge(count_df, on=['x','y1','y2','y3','y4'], how='left')

原理说明

原有代码失效的核心原因是NaN的比较特性:np.nan == np.nan会返回False,导致apply中的条件判断无法匹配含NaN的序列。而groupby的dropna=False参数会将NaN当作独特的分组键,正确统计其出现次数,完美匹配需求。

内容的提问来源于stack exchange,提问作者Joshua Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:10:07