
在数据分析实践中,我们经常需要从一个数据源(例如,详细的交易记录)中提取信息,并将其关联到另一个数据源(例如,汇总的查询条件)。本教程将解决一个特定但常见的挑战:我们有两个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中:
传统的merge操作无法直接处理df2中store列的列表结构,这是实现此目标的主要障碍。
为了解决列表列的关联问题,我们将采用以下核心策略和Pandas功能:
首先,我们创建示例数据框:
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按'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 0as_index=False确保store和month作为列而不是索引,方便后续合并。
使用explode()函数展开df2中的store列表。由于explode会改变索引,我们使用reset_index()来保存原始行索引,以便后续聚合。
# 展开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.0import 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)本教程详细介绍了如何在Pandas中处理涉及列表型列的复杂数据框关联与聚合问题。通过巧妙地结合explode()、groupby()和merge()等Pandas核心功能,我们能够有效地将列表展开、进行多条件匹配,并最终聚合出所需的结果。这种方法不仅解决了列表列的直接合并难题,也为处理更复杂的数据转换任务提供了强大的工具和清晰的思路。掌握这些技巧,将极大地提升你在Pandas中处理复杂数据结构的能力。
以上就是Pandas数据框列表列处理:根据多条件关联与聚合获取最小值的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号