具有选择条件的pandas数据帧中的高效最大选择

时间:2015-03-09 11:54:43

标签: python python-3.x pandas

我有一个pandas数据框,其中包含列{(1}}和user_id。我希望有效且可读地找到与每个用户的最大start_time相关联的所有行。

例如,如果这是我的数据:

start_time

然后我希望找到

user_id   start_time   A    B    C
1         37           a    b    c
1         45           d    e    f
1         45           g    h    i
2         58           j    k    l
2         17           m    n    o
2         58           p    q    r
3          2           s    t    u

我一直在提出类似Conditional selection of data in a pandas DataFrame的解决方案,但找到user_id start_time A B C 1 45 d e f 1 45 g h i 2 58 j k l 2 58 p q r 3 2 s t u 最新user_id的解决方案,而不是每个用户最大值的表格选择{ {1}}的

当然,如果我手动迭代DataFrame很容易,但效率很低。

感谢您的任何指示。

为了方便未来的读者,请生成数据帧:

start time

2 个答案:

答案 0 :(得分:2)

您可以通过user_id列进行分组,然后调用apply并传递一个lambda来过滤结果,其中开始时间等于最大值,我们希望从中生成一个布尔索引。然后我们可以调用reset_index但是由于groupby被过滤的方式,我们将得到重复列的错误,因此我们必须删除此重复列:

In [66]:

gp = df.groupby('user_id')
gp.apply(lambda x: x[x['start_time'] == x['start_time'].max()]).reset_index(drop=True)

Out[66]:
   user_id  start_time  A  B  C
0        1          45  d  e  f
1        1          45  g  g  i
2        2          58  j  k  l
3        2          58  p  q  r
4        3           2  s  t  u

如果我们没有调用reset_index,您就会获得重复的值:

In [67]:

gp.apply(lambda x: x[x['start_time'] == x['start_time'].max()])
Out[67]:
           user_id  start_time  A  B  C
user_id                                
1       1        1          45  d  e  f
        2        1          45  g  g  i
2       3        2          58  j  k  l
        5        2          58  p  q  r
3       6        3           2  s  t  u

内部布尔条件在多索引上生成一个布尔掩码,然后需要将其传递给lambda以生成上述内容:

In [68]:

gp.apply(lambda x: x['start_time'] == x['start_time'].max())
Out[68]:
user_id   
1        0    False
         1     True
         2     True
2        3     True
         4    False
         5     True
3        6     True
Name: start_time, dtype: bool

答案 1 :(得分:1)

或者你可以这样做:

df[df.start_time == df.groupby('user_id')['start_time'].transform(max)]

哪个收益率:

   user_id  start_time  A  B  C
1        1          45  d  e  f
2        1          45  g  h  i
3        2          58  j  k  l
5        2          58  p  q  r
6        3           2  s  t  u