按pandas数据框中的数据分组

时间:2016-12-14 15:49:24

标签: python pandas

我有以下格式的一组点。对于每个Id1,有一组Id2的纬度和经度。对于每组Id1和Id2,我需要组中的第一条记录 除了最后一组,我需要第一个和最后一个记录。请参阅下面的输出。

只是想知道熊猫有没有办法实现这一目标。任何帮助,将不胜感激。感谢。

  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

输出:

  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

2 个答案:

答案 0 :(得分:1)

您可以先找到列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

然后使用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

最后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

如果只需要最后一组改变条件:

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

答案 1 :(得分:1)

这个以熊猫为导向的少一点,但它使用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)

它应该产生:

   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

我希望这会有所帮助。