如何在熊猫中做一个复杂的Groupyby?

时间:2017-05-17 17:33:58

标签: python pandas numpy group-by

我有一个pandas数据框,如:

      a    b   id
1    10    6    1
2     6   -3    1
3    -3   12    1  # id is 1, but needs a tie breaker
4    -2   12    1  # id is 1, but needs a tie breaker
5     4    8    2 
6    12   11    2  
7     3   -5    2
8     3   -5    2

如何创建一个首先获取id列的新数据框,然后每次列b超过10时获取,如果有多行符合此条件,那么请执行绑定通过选择列a中具有最小值的行来断开:

      a    b   id
1    -3   12    1 
2    12   11    2 

我有一个包含2,000,000行和大约10,000 id个值的数据帧,因此for循环非常慢。

4 个答案:

答案 0 :(得分:1)

如果df是您的原始DataFrame,则以下是一种解决方案:

df2 = df[df['b'] > 10]
out = df2.loc[df2.groupby('id')['a'].idxmin()]

你应该得到:

    a   b  id
3  -3  12   1
6  12  11   2

答案 1 :(得分:1)

您可以根据ID进行分组,并应用查询b> 10的函数并查找最小值a。见下文

def my_func(group):
    return df.ix[group.query('b>10')['a'].argmin(), ['a','b']]

print df.groupby(['id']).apply(my_func).reset_index()

这导致

  id   a   b
0   1  -3  12
1   2  12  11

答案 2 :(得分:1)

>>> data = pd.DataFrame({'a': [10, 6, -3, -2, 4, 12, 3, 3], 
'b': [6, -3, 12, 12, 8, 11, -5, -5], 
'id': [1, 1, 1, 1, 2, 2, 2, 2]})

根据DataFrame的条件编写一个过滤b的函数,然后使用a获取idxmin最小的索引。然后,我们将此函数应用于分组数据。

>>> def get_rows(data):
    ...     return data.loc[data.loc[data['b'] > 10].a.idxmin()]

>>> data.groupby('id').apply(get_rows)
     a   b  id
id            
1   -3  12   1
2   12  11   2

答案 3 :(得分:1)

这是另一种解决方案:

while

注意:在这种情况下,您的结果索引将为[0,1]。