Pandas groupby将组中一行的值添加到组的所有行

时间:2018-06-11 13:04:41

标签: python pandas dataframe group-by pandas-groupby

给定一个大致如下的DataFrame df

    TripID  time  Latitude  SectorID  sector_leave_time
 0      42     7      52.5         5                  8
 1      42     8      52.6         5                  8
 2      42     9      52.7         6                 10
 3      42    10      52.8         6                 10
 4       5     9      50.1         2                 10
 5       5    10      50.0         2                 10
 6       5    11      49.9         1                 12
 7       5    12      49.8         1                 12

我已经通过获取扇区内的最大时间戳来计算行程离开扇区的时间。现在,我想在每个行程和扇区的sector_leave_time点为纬度添加另一列,因此DataFrame变为:

    TripID  time  Latitude  SectorID  sector_leave_time  sector_leave_lat
 0      42     7      52.5         5                  8              52.6
 1      42     8      52.6         5                  8              52.6
 2      42     9      52.7         6                 10              52.8
 3      42    10      52.8         6                 10              52.8
 4       5     9      50.1         2                 10              50.0
 5       5    10      50.0         2                 10              50.0
 6       5    11      49.9         1                 12              49.8
 7       5    12      49.8         1                 12              49.8

到目前为止,我只能将sector_leave_lat添加到time == sector_leave_time行,即行程离开行业时,使用以下代码行:

 df['sector_leave_lat'] = df.groupby('TripID').apply(lambda x : x.loc[x['time'] == x['sector_leave_time'], 'Latitude']).reset_index().set_index('level_1')['Latitude']

我知道这条线看起来很糟糕,我想将sector_leave_lat添加到该扇区内该行程的所有条目中。我有点想法,所以我希望有人可以提供帮助。

2 个答案:

答案 0 :(得分:2)

如果您熟悉SQL,问题并不复杂:) 以下代码应该可以解决问题:

#Given your dataframe :
df

   TripID  time  Latitude  SectorID  sector_leave_time
0    42.0   7.0      52.5       5.0                8.0
1    42.0   8.0      52.6       5.0                8.0
2    42.0   9.0      52.7       6.0               10.0
3    42.0  10.0      52.8       6.0               10.0
4     5.0   9.0      50.1       2.0               10.0
5     5.0  10.0      50.0       2.0               10.0
6     5.0  11.0      49.9       1.0               12.0
7     5.0  12.0      49.8       1.0               12.0

# Get the Latitude corresponding to time = sector_leave_time
df_max_lat = df.loc[df_merged.time==df.sector_leave_time, ['TripID', 'Latitude', 'SectorID']]
# Then you have :

   TripID  Latitude  SectorID
1    42.0      52.6       5.0
3    42.0      52.8       6.0
5     5.0      50.0       2.0
7     5.0      49.8       1.0

# Add the max latitude to original dataframe applying a left join
pd.merge(df, df_max_lat, on=['TripID', 'SectorID'], how='left', suffixes=('','_sector_leave'))
# You're getting :
    TripID  time    Latitude    SectorID    sector_leave_time   Latitude_sector_leave
0   42.0    7.0     52.5    5.0     8.0     52.6
1   42.0    8.0     52.6    5.0     8.0     52.6
2   42.0    9.0     52.7    6.0     10.0    52.8
3   42.0    10.0    52.8    6.0     10.0    52.8
4   5.0     9.0     50.1    2.0     10.0    50.0
5   5.0     10.0    50.0    2.0     10.0    50.0
6   5.0     11.0    49.9    1.0     12.0    49.8
7   5.0     12.0    49.8    1.0     12.0    49.8

你去:)

答案 1 :(得分:1)

对于您想要最后一个纬度的每个旅行 - 扇区组合,按时间排序。

df['sector_leave_lat'] = df.sort_values('time').groupby(
    ['TripID', 'SectorID']
).transform('last')['Latitude']

outputs:
   TripID  time  Latitude  SectorID  sector_leave_time  test
0      42     7      52.5         5                  8  52.6
1      42     8      52.6         5                  8  52.6
2      42     9      52.7         6                 10  52.8
3      42    10      52.8         6                 10  52.8
4       5     9      50.1         2                 10  50.0
5       5    10      50.0         2                 10  50.0
6       5    11      49.9         1                 12  49.8
7       5    12      49.8         1                 12  49.8

由于样本数据已经按照每个行程 - 扇区组内的时间排序,因此这里的排序可能是多余的