熊猫groupby / apply与int和string类型具有不同的行为

时间:2019-07-09 23:02:38

标签: python pandas apply pandas-groupby

我有以下数据框

   X    Y
0  A   10
1  A    9
2  A    8
3  A    5
4  B  100
5  B   90
6  B   80
7  B   50

和两个非常相似的不同功能

def func1(x):
    if x.iloc[0]['X'] == 'A':
        x['D'] = 1
    else:
        x['D'] = 0
    return x[['X', 'D']]

def func2(x):
    if x.iloc[0]['X'] == 'A':
        x['D'] = 'u'
    else:
        x['D'] = 'v'
    return x[['X', 'D']]

现在我可以对这些功能进行分组/应用

df.groupby('X').apply(func1)
df.groupby('X').apply(func2)

第一行给我我想要的东西,即

   X  D
0  A  1
1  A  1
2  A  1
3  A  1
4  B  0
5  B  0
6  B  0
7  B  0

但是第二行返回的内容很奇怪

   X  D
0  A  u
1  A  u
2  A  u
3  A  u
4  A  u
5  A  u
6  A  u
7  A  u

所以我的问题是:

  • 有人可以解释为什么类型更改时groupby / apply的行为不同吗?
  • 如何使用func2得到类似的东西?

1 个答案:

答案 0 :(得分:0)

问题很简单,应用于GroupBy的函数应该从不尝试更改接收到的数据框。它是副本(可以安全更改,但更改不会在原始数据帧中看到)还是视图取决于实现。该选择由pandas优化器完成,作为用户,您应该知道它是禁止的。

正确的方法是强制复制:

def func2(x):
    x = x.copy()
    if x.iloc[0]['X'] == 'A':
        x['D'] = 'u'
    else:
        x['D'] = 'v'
    return x[['X', 'D']]

此后,df.groupby('X').apply(func2).reset_index(level=0, drop=True)给出预期结果:

   X  D
0  A  u
1  A  u
2  A  u
3  A  u
4  B  v
5  B  v
6  B  v
7  B  v