PandasDataFrame键值匹配与拆分教程
本文详细介绍了如何利用Pandas DataFrame进行键匹配与数值拆分,旨在解决数据处理中常见的数值分配问题。通过`value_counts()`函数计算键的重复频率,再使用`div()`函数标准化数值,最后通过`merge()`操作将拆分后的数值精确地分配到另一个DataFrame的对应行中。本教程提供示例代码和详细解析,展示了如何根据一个DataFrame中键的频率,将另一个DataFrame中的数值进行拆分,并确保最终结果的索引与原始DataFrame一致。掌握此方法,能有效提升数据处理效率,适用于需要数据聚合、拆分和重构的场景。

1. 问题背景与目标
在数据处理中,我们经常会遇到需要将汇总数据(例如总销售额、总库存量)按某种比例或规则分配到其组成部分(例如单个销售记录、单个库存单位)的场景。本教程聚焦于一个具体问题:给定两个Pandas DataFrame,df1包含重复的键(例如产品ID),df2包含每个唯一键对应的总数值。我们的目标是创建一个新的DataFrame,其结构与df1相似,但df2中的数值已经被“拆分”并按键的出现频率分配到df1的对应行中。
例如,假设我们有以下两个DataFrame:
DataFrame 1 (df1): 包含重复的 id
| id |
|---|
| A |
| B |
| A |
| C |
| A |
| A |
| C |
DataFrame 2 (df2): 包含每个唯一 id 对应的总数值
| id | Col1 | Col2 | Col3 |
|---|---|---|---|
| A | 400 | 100 | 20 |
| B | 200 | 800 | |
| C | 600 | 800 |
期望的输出结果:
| id | Col1 | Col2 | Col3 |
|---|---|---|---|
| A | 100 | 25 | 5 |
| B | 200 | 800 | |
| A | 100 | 25 | 5 |
| C | 300 | 400 | |
| A | 100 | 25 | 5 |
| A | 100 | 25 | 5 |
| C | 300 | 400 |
从期望结果可以看出,id为'A'的记录在df1中出现了4次,因此df2中'A'对应的Col1 (400) 被拆分为 400/4 = 100,Col2 (100) 被拆分为 100/4 = 25,Col3 (20) 被拆分为 20/4 = 5。同样,'C'出现了2次,其数值被拆分为一半。而'B'只出现1次,其数值保持不变。
2. 核心思路与实现步骤
要实现上述目标,我们需要执行以下几个关键步骤:
- 计算键频率: 统计df1中每个id出现的次数。
- 标准化 df2: 将df2中每个id对应的数值除以其在df1中的出现频率。
- 合并数据: 将标准化后的df2与原始df1进行合并。
- 恢复索引: 确保最终输出的DataFrame具有与原始df1相同的索引结构。
我们将使用Pandas库中的value_counts()、div()和merge()函数来高效完成这些操作。
3. 示例代码与详细解析
首先,我们创建示例数据:
import pandas as pd
import numpy as np
# 创建 DataFrame 1
data1 = {'id': ['A', 'B', 'A', 'C', 'A', 'A', 'C']}
df1 = pd.DataFrame(data1)
# 创建 DataFrame 2
data2 = {'id': ['A', 'B', 'C'],
'Col1': [400, 200, 600],
'Col2': [100, np.nan, 800],
'Col3': [20, 800, np.nan]}
df2 = pd.DataFrame(data2)
print("原始 df1:")
print(df1)
print("\n原始 df2:")
print(df2)原始 df1:
id 0 A 1 B 2 A 3 C 4 A 5 A 6 C
原始 df2:
id Col1 Col2 Col3 0 A 400 100.0 20.0 1 B 200 NaN 800.0 2 C 600 800.0 NaN
现在,执行核心逻辑:
# 1. 计算 df1 中 'id' 列的频率
id_counts = df1['id'].value_counts()
print("\nid 频率:")
print(id_counts)
# 2. 标准化 df2: 将 df2 中的数值除以对应的 id 频率
# - set_index('id') 将 'id' 设置为索引,以便与 id_counts 对齐
# - div(id_counts, axis=0) 对齐索引并执行逐行除法
df2_standardized = df2.set_index('id').div(id_counts, axis=0)
print("\n标准化后的 df2:")
print(df2_standardized)
# 3. 合并数据
# - df1.reset_index() 暂时将 df1 的原始索引保存为一列,以便后续恢复
# - merge() 根据 'id' 列进行左连接 (how='left')
# - set_index('index').reindex(df1.index) 恢复原始索引和行顺序
out = (df1.reset_index()
.merge(df2_standardized, on='id', how='left')
.set_index('index').reindex(df1.index)
)
print("\n最终输出:")
print(out)id 频率:
A 4 C 2 B 1 Name: id, dtype: int64
标准化后的 df2:
Col1 Col2 Col3 id A 100.0 25.0 5.0 B 200.0 NaN 800.0 C 300.0 400.0 NaN
最终输出:
id Col1 Col2 Col3 0 A 100.0 25.0 5.0 1 B 200.0 NaN 800.0 2 A 100.0 25.0 5.0 3 C 300.0 400.0 NaN 4 A 100.0 25.0 5.0 5 A 100.0 25.0 5.0 6 C 300.0 400.0 NaN
代码解析:
id_counts = df1['id'].value_counts():
- 这一步计算了df1中'id'列每个唯一值的出现频率。例如,'A'出现4次,'B'出现1次,'C'出现2次。结果是一个Pandas Series,索引是id值,值是频率。
df2_standardized = df2.set_index('id').div(id_counts, axis=0):
- df2.set_index('id'): 将df2的'id'列设置为其索引。这是为了让df2的行索引与id_counts的索引(即id值)对齐,以便进行正确的逐行除法。
- .div(id_counts, axis=0): 对df2中除id列以外的所有数值列执行除法操作。axis=0表示按行进行操作,Pandas会自动根据索引(即id值)将df2的每一行与id_counts中对应的频率值进行匹配并相除。如果df2中的某个单元格为NaN,除法操作会保留NaN。
out = (df1.reset_index().merge(df2_standardized, on='id', how='left').set_index('index').reindex(df1.index)):
- df1.reset_index(): 在合并之前,df1的原始整数索引(0, 1, 2...)很重要,因为我们希望最终输出的DataFrame具有与df1相同的行顺序和索引。reset_index()将当前索引转换为一个名为'index'的普通列,并生成一个新的默认整数索引。
- .merge(df2_standardized, on='id', how='left'):
- 将df1(现在包含原始索引作为'index'列)与df2_standardized进行合并。
- on='id' 指定了合并的键是'id'列。
- how='left' 执行左连接。这意味着df1中的所有行都会被保留,如果df1中的某个id在df2_standardized中没有匹配项(虽然在这个特定问题中不太可能),则对应的Col1, Col2, Col3会填充NaN。
- .set_index('index'): 合并完成后,我们将之前保存的'index'列重新设置回DataFrame的索引。
- .reindex(df1.index): 这一步是可选但推荐的,它确保最终DataFrame的行顺序和索引类型与原始df1完全一致。reindex会根据df1.index的顺序重新排列行,如果原始索引中有重复值,也会正确处理。
4. 注意事项与最佳实践
- 数据类型: 除法操作可能会导致数值列的数据类型从整数变为浮点数(例如int变为float),这是正常的。如果需要,可以使用astype()进行类型转换,但要注意NaN值可能导致无法转换为纯整数。
- NaN 值处理: df2中的NaN值在除法和合并过程中会保持为NaN。如果需要,可以在合并前后使用fillna()进行填充。
- 性能: 对于非常大的DataFrame,merge操作可能会比较耗时。然而,Pandas的底层实现通常是高度优化的。此方法在大多数情况下都是高效且简洁的。
- 键的唯一性: 确保df2中的'id'列是唯一的,否则set_index('id')可能会引发错误或产生非预期的行为。如果df2中id不唯一,需要先对其进行聚合处理。
- 索引管理: reset_index()和set_index().reindex()的组合是确保最终输出的索引和行顺序与原始df1保持一致的常用且稳健的方法。
5. 总结
本教程提供了一种高效且易于理解的Pandas解决方案,用于根据键的出现频率将一个DataFrame的数值拆分并分配到另一个DataFrame的对应行中。通过结合value_counts()计算频率、div()进行标准化以及merge()进行数据整合,我们能够精确地实现复杂的数值分配逻辑。掌握这种模式对于处理涉及数据聚合、拆分和重构的场景非常有用。
终于介绍完啦!小伙伴们,这篇关于《PandasDataFrame键值匹配与拆分教程》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!
Golang组合模式构建树形结构教程
- 上一篇
- Golang组合模式构建树形结构教程
- 下一篇
- PHP连接MongoDB实战教程
-
- 文章 · python教程 | 1小时前 |
- Python列表创建技巧全解析
- 283浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python计算文件实际占用空间技巧
- 349浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- OpenCV中OCR技术应用详解
- 204浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- Pandas读取Django表格:协议关键作用
- 401浏览 收藏
-
- 文章 · python教程 | 4小时前 | 身份验证 断点续传 requests库 PythonAPI下载 urllib库
- Python调用API下载文件方法
- 227浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- Windows7安装RtMidi失败解决办法
- 400浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- Python异步任务优化技巧分享
- 327浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- PyCharm图形界面显示问题解决方法
- 124浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- Python自定义异常类怎么创建
- 450浏览 收藏
-
- 文章 · python教程 | 6小时前 |
- Python抓取赛狗数据:指定日期赛道API教程
- 347浏览 收藏
-
- 文章 · python教程 | 6小时前 |
- Python3中datetime常用转换方式有哪些?
- 464浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3179次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3390次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3419次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4525次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3798次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览

