简体   繁体   English

按熊猫数据框中的数据分组

[英]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 indexingdrop_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM