只用 pandas 获取每组的第一行和最后一行
Posted
技术标签:
【中文标题】只用 pandas 获取每组的第一行和最后一行【英文标题】:Get only the first and last rows of each group with pandas 【发布时间】:2019-05-24 10:36:59 【问题描述】:我是 python 的新手。我有一个巨大的dataframe
,有数百万行和 id。我的数据如下所示:
Time ID X Y
8:00 A 23 100
9:00 B 24 110
10:00 B 25 120
11:00 C 26 130
12:00 C 27 140
13:00 A 28 150
14:00 A 29 160
15:00 D 30 170
16:00 C 31 180
17:00 B 32 190
18:00 A 33 200
19:00 C 34 210
20:00 A 35 220
21:00 B 36 230
22:00 C 37 240
23:00 B 38 250
我想按 id 和 time 对数据进行排序。我想要的预期结果是这样的”
Time ID X Y
8:00 A 23 100
13:00 A 28 150
14:00 A 29 160
18:00 A 33 200
20:00 A 35 220
9:00 B 24 110
10:00 B 25 120
17:00 B 32 190
21:00 B 36 230
23:00 B 38 250
11:00 C 26 130
12:00 C 27 140
16:00 C 31 180
19:00 C 34 210
22:00 C 37 240
15:00 D 30 170
我只想选择 id 的“第一个和最后一个”并消除其余部分。预期结果如下所示:
Time ID X Y
8:00 A 23 100
20:00 A 35 220
9:00 B 24 110
23:00 B 38 250
11:00 C 26 130
22:00 C 37 240
15:00 D 30 170
如何在熊猫中做到这一点?谢谢你的建议
【问题讨论】:
【参考方案1】:使用groupby
,找到每个组的head
和tail
,以及concat
两者。
g = df.groupby('ID')
(pd.concat([g.head(1), g.tail(1)])
.drop_duplicates()
.sort_values('ID')
.reset_index(drop=True))
Time ID X Y
0 8:00 A 23 100
1 20:00 A 35 220
2 9:00 B 24 110
3 23:00 B 38 250
4 11:00 C 26 130
5 22:00 C 37 240
6 15:00 D 30 170
如果您能保证每个 ID 组有至少两行,则不需要drop_duplicates
调用。
详情
g.head(1)
Time ID X Y
0 8:00 A 23 100
1 9:00 B 24 110
3 11:00 C 26 130
7 15:00 D 30 170
g.tail(1)
Time ID X Y
7 15:00 D 30 170
12 20:00 A 35 220
14 22:00 C 37 240
15 23:00 B 38 250
pd.concat([g.head(1), g.tail(1)])
Time ID X Y
0 8:00 A 23 100
1 9:00 B 24 110
3 11:00 C 26 130
7 15:00 D 30 170
7 15:00 D 30 170
12 20:00 A 35 220
14 22:00 C 37 240
15 23:00 B 38 250
【讨论】:
令人印象深刻..你介意向我解释一下pd.concat
在groupby
中的功能是什么吗?
@Arief g.head(1)
和 g.tail(1)
返回两个单独的数据帧;然后我使用pd.concat
将两个DataFrame 垂直连接在一起。 concat
和 groupby
是独立的操作。
非常感谢您提供更详细的解释。如何保存到新的csv?因为我尝试了to.csv
我得到了错误。
@Arief result.to_csv('file.csv')
。如果有帮助记得采纳答案,谢谢:-)
如何考虑按时间和ID排序?因为我尝试了我的数据,我对时间数据感到困惑。【参考方案2】:
如果您创建一个小函数来仅选择 DataFrame 的第一行和最后一行,则可以将其应用于 group-by,如下所示:
df.groupby('ID').apply(lambda x: df.iloc[[0, -1]])
正如其他人所提到的,在“ID”只有一行的情况下,也可以使用.drop_duplicates()
或类似名称过滤掉重复的行。
【讨论】:
以上是关于只用 pandas 获取每组的第一行和最后一行的主要内容,如果未能解决你的问题,请参考以下文章