【问题标题】:Pandas groupby/apply has different behaviour with int and string typesPandas groupby/apply 对 int 和 string 类型有不同的行为
【发布时间】:2019-11-19 12:50:08
【问题描述】:

我有以下数据框

   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 类似的东西?

【问题讨论】:

  • 在这里看不到 groupby 的意义,看来您只是想要:df['D'] = np.where(df['X'].eq('A'), 'u', 'v')
  • 感谢@Erfan,您在这个例子中是对的,但这不是我问的问题
  • 你第二个 df 列 X 只包含 A ,这就是为什么输出只有你
  • @WeNYoBen 两个输出都来自相同的(给定的)输入。也对解释感兴趣。

标签: python pandas apply pandas-groupby


【解决方案1】:

问题只是应用于 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 2020-03-22
    • 2020-03-19
    • 1970-01-01
    • 2018-04-17
    相关资源
    最近更新 更多