0

0

Pandas数据框列表列处理:根据多条件关联与聚合获取最小值

DDD

DDD

发布时间:2025-09-26 14:19:01

|

704人浏览过

|

来源于php中文网

原创

Pandas数据框列表列处理:根据多条件关联与聚合获取最小值

本文将介绍如何在Pandas中处理两个数据框的复杂关联场景。当一个数据框的列包含列表型数据(如商店ID列表),而另一个数据框包含具体条目时,我们面临根据月份匹配和商店ID列表包含关系进行数据聚合的需求。教程将详细演示如何利用explode和merge等Pandas高级功能,高效地从源数据框中提取并计算符合条件的最小值,最终实现数据框的精确合并与转换。

场景描述与挑战

在数据分析实践中,我们经常需要从一个数据源(例如,详细的交易记录)中提取信息,并将其关联到另一个数据源(例如,汇总的查询条件)。本教程将解决一个特定但常见的挑战:我们有两个pandas数据框df1和df2。

df1包含具体的商店、对应的数值(value)和月份信息: | store | value | month | | :---- | :---- | :---- | | 1 | 24 | 1 | | 1 | 28 | 2 | | 2 | 29 | 1 | | 2 | 0 | 2 |

df2包含一个商店ID列表(store)和月份信息: | store | month | | :-------- | :---- | | [1, 2, 3] | 1 | | [2] | 2 |

我们的目标是根据以下两个条件,将df1中的value列的最小值添加到df2中:

  1. df1的month必须与df2的month匹配。
  2. df1的store必须包含在df2的store列表之中。
  3. 如果一个df2行对应的商店列表中有多个商店满足条件,我们需要取这些商店对应的value的最小值。

传统的merge操作无法直接处理df2中store列的列表结构,这是实现此目标的主要障碍。

核心思路与Pandas工具

为了解决列表列的关联问题,我们将采用以下核心策略和Pandas功能:

  1. 预聚合df1: 在进行关联之前,先对df1按照store和month进行分组,并计算每个分组的value最小值。这样做可以简化后续的合并操作,并直接获取我们需要的最小值。
  2. 展开df2的列表列: 使用explode()函数将df2中store列的列表展开,使每个列表元素成为独立的一行。这样,df2的store列就不再是列表,而是单个商店ID,从而可以进行标准的合并操作。
  3. 合并数据框: 将展开后的df2与预聚合的df1进行合并,匹配store和month列。
  4. 重新聚合回原始粒度: 由于explode()操作增加了行数,我们需要再次对合并后的结果进行分组,以恢复到df2的原始行粒度,并为每个原始行找到最终的最小值。
  5. 添加结果列: 使用assign()方法将计算出的最小值作为新列添加到df2中。

代码实现步骤

首先,我们创建示例数据框:

import pandas as pd

# 数据框 df1
data1 = {'store': [1, 1, 2, 2], 'value': [24, 28, 29, 0], 'month': [1, 2, 1, 2]}
df1 = pd.DataFrame(data1)
print("df1:")
print(df1)
# df1:
#    store  value  month
# 0      1     24      1
# 1      1     28      2
# 2      2     29      1
# 3      2      0      2

# 数据框 df2
data2 = {'store': [[1, 2, 3], [2]], 'month': [1, 2]}
df2 = pd.DataFrame(data2)
print("\ndf2:")
print(df2)
# df2:
#        store  month
# 0  [1, 2, 3]      1
# 1        [2]      2

接下来,我们按照上述核心思路逐步实现:

步骤一:预处理源数据框 (df1)

为了确保我们获取的是每个商店在特定月份的最小值,我们先对df1进行分组聚合。

# 对df1按'store'和'month'分组,并计算'value'的最小值
df1_min_values = df1.groupby(['store', 'month'], as_index=False)['value'].min()
print("\ndf1_min_values (预聚合后的df1):")
print(df1_min_values)
# df1_min_values (预聚合后的df1):
#    store  month  value
# 0      1      1     24
# 1      1      2     28
# 2      2      1     29
# 3      2      2      0

as_index=False确保store和month作为列而不是索引,方便后续合并。

步骤二:展开目标数据框 (df2) 的列表列

使用explode()函数展开df2中的store列表。由于explode会改变索引,我们使用reset_index()来保存原始行索引,以便后续聚合。

MusicLM
MusicLM

谷歌平台的AI作曲工具,用文字生成音乐

下载
# 展开df2的'store'列,并保留原始索引
df2_exploded = df2.explode('store').reset_index()
print("\ndf2_exploded (展开后的df2):")
print(df2_exploded)
# df2_exploded (展开后的df2):
#    index store  month
# 0      0     1      1
# 1      0     2      1
# 2      0     3      1
# 3      1     2      2

这里的index列记录了原始df2的行号,这对于后续将结果聚合回原始df2的粒度至关重要。

步骤三:关联与合并

将展开后的df2_exploded与预聚合的df1_min_values进行左连接(how='left'),基于store和month列进行匹配。

# 合并展开后的df2与预聚合的df1
merged_df = df2_exploded.merge(df1_min_values, on=['store', 'month'], how='left')
print("\nmerged_df (合并后的数据框):")
print(merged_df)
# merged_df (合并后的数据框):
#    index store  month  value
# 0      0     1      1   24.0
# 1      0     2      1   29.0
# 2      0     3      1    NaN
# 3      1     2      2    0.0

注意,df2中store为3的行在df1中没有匹配,因此value显示为NaN。

步骤四:聚合回原始粒度

现在,我们需要根据df2的原始行索引(index列)对merged_df进行分组,并计算每个原始行的value最小值。

# 根据原始索引聚合,获取每个原始行的最小值
final_values = merged_df.groupby('index')['value'].min()
print("\nfinal_values (最终计算出的值):")
print(final_values)
# final_values (最终计算出的值):
# index
# 0    24.0
# 1     0.0
# Name: value, dtype: float64

对于原始df2的第0行 ([1, 2, 3], month=1),合并后得到了24.0、29.0和NaN,其最小值为24.0。 对于原始df2的第1行 ([2], month=2),合并后得到了0.0,其最小值为0.0。

步骤五:整合结果

最后,使用assign()方法将计算出的final_values添加到原始的df2中,形成最终结果。

# 将结果添加到原始df2中
df2_final = df2.assign(value=final_values)
print("\ndf2_final (最终结果数据框):")
print(df2_final)
# df2_final (最终结果数据框):
#        store  month  value
# 0  [1, 2, 3]      1   24.0
# 1        [2]      2    0.0

完整示例代码

import pandas as pd

# 1. 数据准备
data1 = {'store': [1, 1, 2, 2], 'value': [24, 28, 29, 0], 'month': [1, 2, 1, 2]}
df1 = pd.DataFrame(data1)

data2 = {'store': [[1, 2, 3], [2]], 'month': [1, 2]}
df2 = pd.DataFrame(data2)

print("原始df1:")
print(df1)
print("\n原始df2:")
print(df2)

# 2. 核心处理逻辑
# 步骤一:预处理源数据框df1,获取每个store和month组合的value最小值
df1_min_values = df1.groupby(['store', 'month'], as_index=False)['value'].min()

# 步骤二:展开目标数据框df2的列表列,并保存原始索引
df2_exploded = df2.explode('store').reset_index()

# 步骤三:将展开后的df2与预处理的df1进行左连接
merged_df = df2_exploded.merge(df1_min_values, on=['store', 'month'], how='left')

# 步骤四:根据原始索引聚合,获取每个原始df2行的value最小值
# 如果存在NaN,min()函数会忽略NaN,除非所有值都是NaN。
final_values = merged_df.groupby('index')['value'].min()

# 步骤五:将结果添加到原始df2中
df2_result = df2.assign(value=final_values)

print("\n最终结果df2:")
print(df2_result)

注意事项

  1. 性能考虑: explode()操作会显著增加数据框的行数。如果df2的列表列包含大量元素,且df2本身行数很多,这可能会导致内存消耗增加和计算时间延长。对于极大数据集,可能需要考虑其他优化策略,例如使用apply配合列表推导式,但通常explode在性能上优于纯Python循环。
  2. NaN值的处理: 在合并过程中,如果df2_exploded中的某个store或month组合在df1_min_values中没有匹配项,那么value列将填充为NaN。min()函数在计算时会默认忽略NaN值。如果希望NaN参与计算(例如,将其视为0),则需要在聚合前进行填充(fillna(0))。
  3. 索引管理: explode()会重置索引。通过reset_index()创建的index列是追踪原始行归属的关键。理解并正确使用这个索引对于将结果聚合回原始数据框至关重要。
  4. 数据类型: 最终的value列可能会因为NaN值的引入而变为浮点型(float)。如果需要整数类型,且确定没有NaN或已处理NaN,可以使用astype(int)进行类型转换。

总结

本教程详细介绍了如何在Pandas中处理涉及列表型列的复杂数据框关联与聚合问题。通过巧妙地结合explode()、groupby()和merge()等Pandas核心功能,我们能够有效地将列表展开、进行多条件匹配,并最终聚合出所需的结果。这种方法不仅解决了列表列的直接合并难题,也为处理更复杂的数据转换任务提供了强大的工具和清晰的思路。掌握这些技巧,将极大地提升你在Pandas中处理复杂数据结构的能力。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

62

2025.12.04

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

309

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

579

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

102

2025.10.23

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

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

93

2025.08.29

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

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

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