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

分组统计空值:为何Pandas内置.isna().sum()方法无法生效?

问题:LeetCode「找出所有未进行交易的访客」分组统计报错原因分析

问题背景

我正在解决LeetCode的「找出所有未进行交易的访客」问题,使用的数据如下:

data = [[1, 23], [2, 9], [4, 30], [5, 54], [6, 96], [7, 54], [8, 54]]
visits = pd.DataFrame(data, columns=['visit_id', 'customer_id']).astype({'visit_id':'Int64', 'customer_id':'Int64'})
data = [[2, 5, 310], [3, 5, 300], [9, 5, 200], [12, 1, 910], [13, 2, 970]]
transactions = pd.DataFrame(data, columns=['transaction_id', 'visit_id', 'amount']).astype({'transaction_id':'Int64', 'visit_id':'Int64', 'amount':'Int64'})

数据展示:

Visits
+----------+-------------+
| visit_id | customer_id |
+----------+-------------+
| 1        | 23          |
| 2        | 9           |
| 4        | 30          |
| 5        | 54          |
| 6        | 96          |
| 7        | 54          |
| 8        | 54          |
+----------+-------------+

Transactions
+----------------+----------+--------+
| transaction_id | visit_id | amount |
+----------------+----------+--------+
| 2              | 5        | 310    |
| 3              | 5        | 300    |
| 9              | 5        | 200    |
| 12             | 1        | 910    |
| 13             | 2        | 970    |
+----------------+----------+--------+

问题要求输出每个customer_id对应的无交易访问次数(非零值),预期结果:

+-------------+----------------+
| customer_id | count_no_trans |
+-------------+----------------+
| 54          | 2              |
| 30          | 1              |
| 96          | 1              |
+-------------+----------------+

解题步骤

  • 移除transactions中visit_id重复的行
  • 将visits与处理后的transactions按visit_id左连接
  • 按customer_id分组,统计每组中空值行数(无交易的访问次数)

步骤1和2的代码:

df = pd.merge(left=visits,
    right = transactions.drop_duplicates(subset = ['visit_id']),
    how = 'left',
    on = 'visit_id')

代码对比与报错

使用自定义聚合函数的写法可以正常运行:

df1 = (df[df['transaction_id'].isna()]
    .groupby('customer_id', as_index = False)['transaction_id']
    .agg(lambda x: x.isna().sum())).rename(columns = {'transaction_id':'count_no_trans'})

但直接链式调用.isna().sum()会报错:

df2 = (df[df['transaction_id'].isna()]
    .groupby('customer_id', as_index = False)['transaction_id']
    .isna().sum().rename(columns = {'transaction_id':'count_no_trans'}))

报错信息:

AttributeError: 'SeriesGroupBy' object has no attribute 'isna'

报错原因

核心问题在于**groupby之后得到的是SeriesGroupBy对象,不是普通的Series**:

  • 普通Pandas Series有.isna()方法,用来逐个元素检测是否为空;
  • 但SeriesGroupBy是分组后的聚合容器,它只提供聚合类方法(比如.sum()、.mean()、.agg()),没有.isna()这种元素级的方法。

可行代码里的.agg(lambda x: x.isna().sum()),是把每个分组后的子Series传给lambda函数,此时x是普通Series,所以能调用.isna();而报错代码直接在SeriesGroupBy上调用.isna(),自然找不到这个属性。

另外补充个小优化:你已经提前筛选了df[df['transaction_id'].isna()],这部分数据里的transaction_id全是空值,统计次数直接用.size()更高效:

df1 = df[df['transaction_id'].isna()].groupby('customer_id', as_index=False).size().rename(columns={'size':'count_no_trans'})

内容的提问来源于stack exchange,提问作者Max Zhou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:49:59