提问人:R_Student 提问时间:9/20/2023 最后编辑:halferR_Student 更新时间:10/15/2023 访问量:49
链式方法分组和计算 Pandas DataFrame 中的差异
Chain method grouping and calculating differences in a Pandas DataFrame
问:
我有一个具有以下结构的 Pandas DataFrame:
import pandas as pd
data = {
'glob_order': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
'trans': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C'],
'chain': [1, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2],
'date': ['1/08/2023', '2/08/2023', '3/08/2023', '4/08/2023', '5/08/2023', '6/08/2023', '7/08/2023', '8/08/2023', '9/08/2023', '10/08/2023', '11/08/2023']
}
df = pd.DataFrame(data)
# Convert 'date' column to datetime
df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y')
print(df)
我想执行两个操作:
- 按“trans”和“chain”列对 DataFrame 进行分组,然后从每个组中选择第一行。
- 创建一个名为“delta”的新列,该列表示每个组中当前日期与上一个日期之间的天数差。
我尝试了以下代码:
(df
.groupby(['trans', 'chain'])
.first()
.assign(
delta=lambda x: (x['date'] - x['date'].shift(1)).dt.total_seconds() / (60*60*24),
).reset_index()
)
但是,我得到的输出并不像预期的那样。它似乎在每个单独组的第一个增量计算中插入 NaN,这不是我想要的
反式 | 链 | glob_order | 日期 | 三角洲 |
---|---|---|---|---|
一个 | 1 | 1 | 2023-08-01 | 南 |
一个 | 2 | 3 | 2023-08-03 | 2.0 |
B | 1 | 5 | 2023-08-05 | 2.0 |
B | 2 | 7 | 2023-08-07 | 2.0 |
C | 1 | 8 | 2023-08-08 | 1.0 |
C | 2 | 10 | 2023-08-10 | 2.0 |
我想知道为什么会发生这种情况,以及我需要做什么才能获得所需的输出。
这是我想要的输出
反式 | 链 | glob_order | 日期 | 三角洲 |
---|---|---|---|---|
一个 | 1 | 1 | 2023-08-01 | 南 |
一个 | 2 | 3 | 2023-08-03 | 2.0 |
B | 1 | 5 | 2023-08-05 | 南 |
B | 2 | 7 | 2023-08-07 | 2.0 |
C | 1 | 8 | 2023-08-08 | 南 |
C | 2 | 10 | 2023-08-10 | 2.0 |
我正在寻找一种解决方案,使用类似于链接的方法来提高清晰度和可读性,因为我对 Python 非常陌生。
答:
1赞
Andrej Kesely
9/20/2023
#1
如果我理解正确,你想要:
- 作为第一步,按 / 分组,获取第一行
"trans"
"chain"
- 作为第二步,分组依据并得到天数之间的差值
"trans"
我不认为简单的链接是可能的,但你可以使用运算符(但为了可读性,我建议将其拆分为两个单独的命令)::=
df = (df := df.groupby(["trans", "chain"], as_index=False).first()).assign(
delta=df.groupby("trans")["date"].diff().dt.days
)
print(df)
指纹:
trans chain glob_order date delta
0 A 1 1 2023-08-01 NaN
1 A 2 3 2023-08-03 2.0
2 B 1 5 2023-08-05 NaN
3 B 2 7 2023-08-07 2.0
4 C 1 8 2023-08-08 NaN
5 C 2 10 2023-08-10 2.0
评论
0赞
R_Student
9/20/2023
嘿安德烈!我记得你在其他问题上帮了我很多!!是的,你是对的,我忘记了后来 Trans 单独进行了摸索作为第二步,你能解释一下 : = 是做什么的吗?,以及你为什么选择 as_index=False 我发誓 Python 充满了神秘感,非常感谢我的男人
1赞
Andrej Kesely
9/20/2023
@R_Student我已添加到第一个不调用后一个。as_index=False
.groupby
.reset_index()
1赞
mozway
9/20/2023
为了使用两个答案中最好的答案,我会采用您的方法和 () 中的 lambda,海象在这里有点奇怪。如果你有很长的命令链,那将是不切实际的。assign
delta=lambda d: d.groupby("trans")["date"].diff().dt.days
2赞
Panda Kim
9/20/2023
#2
与 Groupby 和 Lambda 功能一起使用。assign
(df.groupby(['trans', 'chain']).first()
.assign(delta=lambda x: x.groupby(level=0)['date'].diff().dt.days)
.reset_index())
输出:
trans chain glob_order date delta
0 A 1 1 2023-08-01 NaN
1 A 2 3 2023-08-03 2.0
2 B 1 5 2023-08-05 NaN
3 B 2 7 2023-08-07 2.0
4 C 1 8 2023-08-08 NaN
5 C 2 10 2023-08-10 2.0
评论
0赞
R_Student
9/20/2023
哦,天哪,这太酷了,你能解释一下 x.groyby 0 级吗?你的代码到底是怎么回事!
0赞
Panda Kim
9/20/2023
首先,运行代码。然后,在结果中使用 level = 0() 的 group by index。df.groupby(['trans', 'chain']).first()
trans
评论