0

0

使用Pandas和NumPy计算首个唯一值对应的累计总和

霞舞

霞舞

发布时间:2025-11-03 13:20:35

|

830人浏览过

|

来源于php中文网

原创

使用Pandas和NumPy计算首个唯一值对应的累计总和

本文详细介绍了如何使用pandas和numpy高效地在数据集中为每个唯一客户id的首次出现计算并显示其总销售额,而后续记录则显示为零。通过巧妙结合`series.duplicated()`、`groupby.transform()`和`numpy.where()`函数,可以简洁且高性能地实现这一数据转换,生成所需的累计销售列,适用于数据分析和报告场景。

在数据分析中,我们经常需要对特定分组的数据进行汇总,并只在每个分组的首次出现时显示这个汇总值,而后续的记录则显示为零。这种需求在处理客户交易、项目里程碑或任何具有唯一标识符的序列数据时尤为常见。例如,我们可能需要计算每个客户的总销售额,但只希望在客户的第一条销售记录旁显示这个总额,其余记录则留空或显示为零,以避免重复计算或视觉上的混淆。

问题描述与示例数据

假设我们有一个包含客户ID、日期和每日销售额的数据集,如下所示:

  ClientID        Date  Total sales
0        A  01-01-2000          100
1        A  01-02-2000          100
2        A  01-03-2000          100
3        B  01-01-2000           50
4        B  01-02-2000           50
5        C  01-01-2000           70
6        C  01-02-2000           70
7        C  01-03-2000           70
8        D  01-01-2000           20
9        D  01-02-2000           20

我们的目标是创建一个名为Cumulative Sales的新列。对于每个唯一的ClientID,该列应在其首次出现时显示该客户的所有Total sales之和,而在该客户ID的后续记录中显示0。

期望的输出结果如下:

  ClientID        Date  Total sales  Cumulative Sales
0        A  01-01-2000          100               300
1        A  01-02-2000          100                 0
2        A  01-03-2000          100                 0
3        B  01-01-2000           50               100
4        B  01-02-2000           50                 0
5        C  01-01-2000           70               210
6        C  01-02-2000           70                 0
7        C  01-03-2000           70                 0
8        D  01-01-2000           20                40
9        D  01-02-2000           20                 0

解决方案:Pandas与NumPy的结合

为了高效地实现这一目标,我们可以利用Pandas库的强大数据处理能力,并结合NumPy的条件逻辑函数。核心思想是:

  1. 识别出每个ClientID的首次出现。
  2. 计算每个ClientID的总销售额。
  3. 根据首次出现的条件,将总销售额赋值给新列,否则赋值为零。

我们将使用以下三个关键函数:

  • pandas.Series.duplicated():用于标记重复值,可以轻松识别每个分组的首次出现。
  • pandas.core.groupby.DataFrameGroupBy.transform():用于在分组后执行聚合操作,并将结果广播回原始DataFrame的索引。
  • numpy.where():一个强大的条件函数,根据条件数组选择不同来源的值。

代码实现

首先,我们创建示例DataFrame:

零一万物开放平台
零一万物开放平台

零一万物大模型开放平台

下载
import pandas as pd
import numpy as np

data = {
    'ClientID': ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'D', 'D'],
    'Date': ['01-01-2000', '01-02-2000', '01-03-2000', '01-01-2000', '01-02-2000',
             '01-01-2000', '01-02-2000', '01-03-2000', '01-01-2000', '01-02-2000'],
    'Total sales': [100, 100, 100, 50, 50, 70, 70, 70, 20, 20]
}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date']) # 将日期列转换为日期时间类型

print("原始DataFrame:")
print(df)

现在,应用解决方案来创建Cumulative Sales列:

df['Cumulative Sales'] = np.where(
    df['ClientID'].duplicated(),  # 条件:如果ClientID是重复的(即非首次出现)
    0,                            # 如果条件为真,则赋值为0
    df.groupby('ClientID')['Total sales'].transform('sum') # 如果条件为假(即首次出现),则计算该ClientID的总销售额
)

print("\n处理后的DataFrame:")
print(df)

结果展示

运行上述代码后,我们将得到与期望完全一致的输出:

原始DataFrame:
  ClientID       Date  Total sales
0        A 2000-01-01          100
1        A 2000-01-02          100
2        A 2000-01-03          100
3        B 2000-01-01           50
4        B 2000-01-02           50
5        C 2000-01-01           70
6        C 2000-01-02           70
7        C 2000-01-03           70
8        D 2000-01-01           20
9        D 2000-01-02           20

处理后的DataFrame:
  ClientID       Date  Total sales  Cumulative Sales
0        A 2000-01-01          100               300
1        A 2000-01-02          100                 0
2        A 2000-01-03          100                 0
3        B 2000-01-01           50               100
4        B 2000-01-02           50                 0
5        C 2000-01-01           70               210
6        C 2000-01-02           70                 0
7        C 2000-01-03           70                 0
8        D 2000-01-01           20                40
9        D 2000-01-02           20                 0

核心函数解析

  1. df['ClientID'].duplicated()

    • 这个方法返回一个布尔型Series,其长度与df['ClientID']相同。
    • 对于每个元素,如果它是其所在Series中第一次出现的值,则返回False;如果它是重复出现的值(即非首次出现),则返回True。
    • 在我们的例子中,df['ClientID'].duplicated()会生成[False, True, True, False, True, False, True, True, False, True],这正是我们用来判断是否为首次出现的条件。
  2. df.groupby('ClientID')['Total sales'].transform('sum')

    • df.groupby('ClientID'):将DataFrame按ClientID列进行分组。
    • ['Total sales']:选择Total sales列进行聚合操作。
    • .transform('sum'):这是一个非常关键的步骤。transform()方法会在每个分组上应用聚合函数(这里是sum),然后将聚合结果广播回原始DataFrame的索引。这意味着,对于同一个ClientID的所有行,transform('sum')都会返回相同的总销售额。
    • 例如,对于ClientID 'A',transform('sum')会返回300,并且这个300会被填充到所有ClientID 'A'的行中。
  3. np.where(condition, x, y)

    • 这是一个NumPy的通用函数,用于根据条件选择元素。
    • condition:一个布尔型数组或Series。
    • x:当condition为True时选择的值。
    • y:当condition为False时选择的值。
    • 在本例中:
      • condition是df['ClientID'].duplicated()。
      • x是0(因为当ClientID是重复的,我们希望Cumulative Sales为0)。
      • y是df.groupby('ClientID')['Total sales'].transform('sum')(因为当ClientID不是重复的,我们希望Cumulative Sales为该客户的总销售额)。

注意事项

  • 数据顺序: duplicated()方法默认会根据数据在DataFrame中的出现顺序来判断是否为“首次”。如果DataFrame的顺序很重要(例如,你希望某个特定日期被认为是首次),请确保在应用此方法前,DataFrame已按相关列(如ClientID和Date)正确排序。例如:df = df.sort_values(['ClientID', 'Date'])。
  • 性能: 这种结合groupby().transform()和np.where()的方法在处理大型数据集时通常非常高效,因为它利用了Pandas和NumPy的底层优化。
  • 灵活性: 除了sum,你还可以使用transform()结合其他聚合函数(如mean, max, min, count等),以满足不同的业务需求。

总结

通过本教程,我们学习了如何利用Pandas和NumPy的强大功能,高效地为数据集中每个唯一标识符的首次出现计算并填充聚合值,而将其余重复项设置为零。这种方法结构清晰、性能优越,是处理类似数据转换任务的推荐实践。掌握duplicated()、groupby().transform()和np.where()的组合使用,将极大地提升你在数据处理和分析中的效率。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

54

2025.12.04

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

283

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

256

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

122

2025.08.07

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

283

2024.02.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.8万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.7万人学习

Django 教程
Django 教程

共28课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号