pandas 中如何在 Groupby 和 Concat 之后分配数据
How to Assign Data after Groupby and Concat in pandas
我是 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 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
我只想选择 "The first and the last" 的 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
我使用了这个代码:
df = pd.read_csv("data.csv")
g = df.groupby('ID')
g_1 = pd.concat([g.head(1),g.tail(1)]).drop_duplicates().sort_values('ID').reset_index(drop=True)
g_1.to_csv('result.csv')
但我想在新列中将每一行分配或注释为 "first" 和 "last"。
我的预期结果如下所示:
Time ID X Y Annotation
8:00 A 23 100 First
20:00 A 35 220 Last
9:00 B 24 110 First
23:00 B 38 250 Last
11:00 C 26 130 First
22:00 C 37 240 Last
15:00 D 30 170
有人可以帮我解决这个问题吗?请多多指教谢谢
排序后
不需要 groupby
使用 drop_duplicates
df=pd.concat([df.drop_duplicates(['ID']).assign(sign='first'),df.drop_duplicates(['ID'],keep='last').assign(sign='last')]).sort_values('ID')
df
Time ID X Y sign
0 8:00 A 23 100 first
4 20:00 A 35 220 last
5 9:00 B 24 110 first
9 23:00 B 38 250 last
10 11:00 C 26 130 first
14 22:00 C 37 240 last
15 15:00 D 30 170 first
15 15:00 D 30 170 last
您可以使用 groupby agg,first 和 last。非常适合列注释。作为奖励,这将适用于原始数据框,因此无需排序
df3.groupby('ID').agg(['first', 'last']).stack().reset_index().rename(columns = {'level_1': 'Annotation'})
ID Annotation Time X Y
0 A first 8:00 23 100
1 A last 20:00 35 220
2 B first 9:00 24 110
3 B last 23:00 38 250
4 C first 11:00 26 130
5 C last 22:00 37 240
6 D first 15:00 30 170
7 D last 15:00 30 170
尝试:
df.groupby('ID').agg(['first','last'])\
.stack(1).reset_index()\
.rename(columns={'level_1':'Annotation'})
输出:
ID Annotation Time X Y
0 A first 8:00 23 100
1 A last 20:00 35 220
2 B first 9:00 24 110
3 B last 23:00 38 250
4 C first 11:00 26 130
5 C last 22:00 37 240
6 D first 15:00 30 170
7 D last 15:00 30 170
我是 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 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
我只想选择 "The first and the last" 的 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
我使用了这个代码:
df = pd.read_csv("data.csv")
g = df.groupby('ID')
g_1 = pd.concat([g.head(1),g.tail(1)]).drop_duplicates().sort_values('ID').reset_index(drop=True)
g_1.to_csv('result.csv')
但我想在新列中将每一行分配或注释为 "first" 和 "last"。
我的预期结果如下所示:
Time ID X Y Annotation
8:00 A 23 100 First
20:00 A 35 220 Last
9:00 B 24 110 First
23:00 B 38 250 Last
11:00 C 26 130 First
22:00 C 37 240 Last
15:00 D 30 170
有人可以帮我解决这个问题吗?请多多指教谢谢
排序后
不需要groupby
使用 drop_duplicates
df=pd.concat([df.drop_duplicates(['ID']).assign(sign='first'),df.drop_duplicates(['ID'],keep='last').assign(sign='last')]).sort_values('ID')
df
Time ID X Y sign
0 8:00 A 23 100 first
4 20:00 A 35 220 last
5 9:00 B 24 110 first
9 23:00 B 38 250 last
10 11:00 C 26 130 first
14 22:00 C 37 240 last
15 15:00 D 30 170 first
15 15:00 D 30 170 last
您可以使用 groupby agg,first 和 last。非常适合列注释。作为奖励,这将适用于原始数据框,因此无需排序
df3.groupby('ID').agg(['first', 'last']).stack().reset_index().rename(columns = {'level_1': 'Annotation'})
ID Annotation Time X Y
0 A first 8:00 23 100
1 A last 20:00 35 220
2 B first 9:00 24 110
3 B last 23:00 38 250
4 C first 11:00 26 130
5 C last 22:00 37 240
6 D first 15:00 30 170
7 D last 15:00 30 170
尝试:
df.groupby('ID').agg(['first','last'])\
.stack(1).reset_index()\
.rename(columns={'level_1':'Annotation'})
输出:
ID Annotation Time X Y
0 A first 8:00 23 100
1 A last 20:00 35 220
2 B first 9:00 24 110
3 B last 23:00 38 250
4 C first 11:00 26 130
5 C last 22:00 37 240
6 D first 15:00 30 170
7 D last 15:00 30 170