[英]Group by data in pandas dataframe
I have a set of points in the following format. 我有以下格式的几点。 For each Id1, there is a set of Id2's with their latitude and longitude. 对于每个Id1,都有一组Id2及其纬度和经度。 For each group of Id1 and Id2, I need the first record in the group except for the last group, in which i need both the first and last records. 对于Id1和Id2的每个组,我需要该组中的第一个记录,但最后一个组除外,在该组中,我需要第一个和最后一个记录。 Please see below the output. 请参见下面的输出。
Just wondering is there a way in pandas I can achieve this. 我只是想知道熊猫有没有办法实现这一目标。 Any help would be appreciated. 任何帮助,将不胜感激。 Thanks. 谢谢。
Id1 Id2 Latitude Longitude
179 183 33.67 -83.24
179 183 31.33 -83.11
179 184 33.58 -83.34
179 184 33.61 -83.14
179 185 33.60 -83.54
179 185 33.60 -83.54
180 185 33.67 -83.64
180 185 33.79 -83.74
180 186 33.81 -83.84
180 186 33.81 -83.84
Output: 输出:
Id1 Id2 Latitude Longitude
179 183 33.67 -83.24
179 184 33.58 -83.34
179 185 33.60 -83.54
179 185 33.60 -83.54
179 186 33.79 -83.74
179 186 33.81 -83.84
180 185 33.67 -83.64
180 186 33.81 -83.84
180 186 33.81 -83.88
You can first find last value of column Id2
, then filter where are no last values by boolean indexing
and drop_duplicates
: 您可以首先找到Id2
列的最后一个值,然后通过boolean indexing
和drop_duplicates
过滤哪里没有最后值:
last_row = df['Id2'].iloc[-1]
print (last_row)
186
df1 = df[df.Id2 != last_row].drop_duplicates(['Id1','Id2'])
print (df1)
Id1 Id2 Latitude Longitude
0 179 183 33.67 -83.24
2 179 184 33.58 -83.34
4 179 185 33.60 -83.54
7 180 185 33.67 -83.64
Then filter values with last value in Id2
: 然后过滤Id2
最后一个值的值:
df2 = df[df.Id2 == last_row]
print (df2)
Id1 Id2 Latitude Longitude
5 179 186 33.81 -83.84
6 179 186 33.81 -83.84
9 180 186 33.81 -83.84
10 180 186 33.81 -83.84
And last concat
together: 而在去年concat
在一起:
print (pd.concat([df1,df2]).reset_index(drop=True))
Id1 Id2 Latitude Longitude
0 179 183 33.67 -83.24
1 179 184 33.58 -83.34
2 179 185 33.60 -83.54
3 180 185 33.67 -83.64
4 179 186 33.81 -83.84
5 179 186 33.81 -83.84
6 180 186 33.81 -83.84
7 180 186 33.81 -83.84
If need only last group change condition: 如果只需要最后一组更改条件:
lastId1 = df['Id1'].iloc[-1]
print (lastId1)
180
lastId2 = df['Id2'].iloc[-1]
print (lastId2)
186
mask = (df.Id1 == lastId1) & (df.Id2 == lastId2)
df1 = df[~mask].drop_duplicates(['Id1','Id2']).drop_duplicates(['Id1','Id2'])
print (df1)
Id1 Id2 Latitude Longitude
0 179 183 33.67 -83.24
2 179 184 33.58 -83.34
4 179 185 33.60 -83.54
5 179 186 33.81 -83.84
7 180 185 33.67 -83.64
df2 = df[mask]
print (df2)
Id1 Id2 Latitude Longitude
9 180 186 33.81 -83.84
10 180 186 33.81 -83.84
print (pd.concat([df1,df2]).reset_index(drop=True))
Id1 Id2 Latitude Longitude
0 179 183 33.67 -83.24
1 179 184 33.58 -83.34
2 179 185 33.60 -83.54
3 179 186 33.81 -83.84
4 180 185 33.67 -83.64
5 180 186 33.81 -83.84
6 180 186 33.81 -83.84
This one is a bit less pandas-oriented but it uses group-by
operations: 这是一个不太面向熊猫的方法,但它使用了group-by
操作:
# Function to check if row values are equal to last_group values
def compare_to_groups(x, last_groups):
return any((x[['Id1','Id2']] == last_groups[i]).all(1).any() for i in range(len(last_groups)))
# Get the last groups
last_groups = df.groupby('Id1')['Id1','Id2'].last().values
# Apply to each group
df.groupby(['Id1','Id2']).apply(lambda x: x if compare_to_groups(x, last_groups) else x.head(1)).reset_index(drop=True)
It should yield: 它应该产生:
Id1 Id2 Latitude Longitude
0 179 183 33.67 -83.24
1 179 184 33.58 -83.34
2 179 185 33.60 -83.54
3 179 185 33.60 -83.54
4 180 185 33.67 -83.64
5 180 186 33.81 -83.84
6 180 186 33.81 -83.84
I hope this helps. 我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.