python - Pandas 拆分列并聚合结果与索引中的重复项
问题描述
我有以下数据框:
ID Type Value
1 A 311
1 A 223
1 B 1233
2 A 424
2 A 553
3 A 11
3 B 4
3 B 5
我正在尝试通过拆分“类型”列来聚合“ID”列,这样每个 ID 都有自己的行以及 A 类型和 B 类型的相应列。在“A”和“B”列中,我想分配行中每个相应值的第一次出现。如果缺少 A 或 B(或两者),我想分配 NaN。为了清楚地说明这个想法,以下示例描述了我正在寻找的结果:
ID A B
1 311 1233
2 424 NaN
3 11 4
结果保留了 A 出现的第一个值(同时忽略 A 223 的第二个值)。由于 ID 1 中的 B 没有第二个值,因此它只保留值 1233。此逻辑适用于其他 ID。
我一直在尝试使用.pivot
using解决这个问题
df.pivot(columns="Type",values="Value")
这有助于我分离 Type 列,这样我得到:
Type A B
0 311 NaN
1 223 NaN
2 NaN 1233
3 11 4
但是我无法将 ID 列作为索引传递,因为它给了我错误:
ValueError: Index contains duplicate entries, cannot reshape
但是,在 ID 列上使用drop_duplicates
会导致数据丢失。有什么方便的方法可以在熊猫中进行这样的操作吗?
解决方案
您需要先删除重复项,然后再进行旋转。
df.drop_duplicates(['ID', 'Type']).pivot('ID', 'Type', 'Value')
Type A B
ID
1 311.0 1233.0
2 424.0 NaN
3 11.0 4.0
或者,pivot_table
与 一起使用aggfunc='first'
:
df.pivot_table(index='ID', columns='Type', values='Value', aggfunc='first')
Type A B
ID
1 311.0 1233.0
2 424.0 NaN
3 11.0 4.0
性能
这实际上取决于您的数据和组数。最好是在您自己的数据上进行测试。
df_ = df.copy()
df = pd.concat([df_] * 10000, ignore_index=True)
%timeit df.pivot_table(index='ID', columns='Type', values='Value', aggfunc='first')
%timeit df.drop_duplicates(['ID', 'Type']).pivot('ID', 'Type', 'Value')
%timeit df.groupby(['ID', 'Type']).Value.first().unstack(1)
15.2 ms ± 272 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.63 ms ± 98 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.34 ms ± 246 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
推荐阅读
- pygame - 收到错误消息:ModuleNotFoundError: No module named 'pygame'
- javascript - 返回页面上脚本的多个日期
- angular - 如何在一行中导入多个组件和类 - 角度?
- java - 如何使用 Maven 解决对 JNLP 的依赖
- go - IPv4 地址 BigEndian 字节顺序
- javascript - 如何使用内部函数更改外部变量的值?
- postgresql - 如何读取用户表中的记录?
- swift - 如何在循环中调用 childByAutoId 一次?(迅速)
- c - 从整数(指针)生成指针(整数)而不进行强制转换
- python-3.x - 未找到带有参数“(”,)”的“update_task”的反向操作。尝试了 1 种模式:['update/(?P
[^/]+)/$']