【问题标题】:Python Pandas: how to add a totally new column to a data frame inside of a groupby/transform operationPython Pandas:如何在 groupby/transform 操作中向数据框中添加一个全新的列
【发布时间】:2012-09-05 13:48:08
【问题描述】:

我想在我的数据中标记一些分位数,对于 DataFrame 的每一行,我希望在一个名为例如的新列中的条目"xtile" 来保存这个值。

例如,假设我创建一个这样的数据框:

import pandas, numpy as np
dfrm = pandas.DataFrame({'A':np.random.rand(100), 
                         'B':(50+np.random.randn(100)), 
                         'C':np.random.randint(low=0, high=3, size=(100,))})

假设我编写了自己的函数来计算数组中每个元素的五分位数。我对此有自己的功能,但例如只需参考 scipy.stats.mstats.mquantile。

import scipy.stats as st
def mark_quintiles(x, breakpoints):
    # Assume this is filled in, using st.mstats.mquantiles.
    # This returns an array the same shape as x, with an integer for which
    # breakpoint-bucket that entry of x falls into.

现在,真正的问题是如何使用transform 向数据添加新列。像这样的:

def transformXtiles(dataFrame, inputColumnName, newColumnName, breaks):
    dataFrame[newColumnName] = mark_quintiles(dataFrame[inputColumnName].values, 
                                              breaks)
    return dataFrame

然后:

dfrm.groupby("C").transform(lambda x: transformXtiles(x, "A", "A_xtile", [0.2, 0.4, 0.6, 0.8, 1.0]))

问题是上面的代码不会添加新列“A_xtile”。它只是返回我的数据框不变。如果我首先添加一个充满虚拟值的列,例如 NaN,称为“A_xtile”,那么它确实成功地覆盖了该列以包含正确的五分位数标记。

但是对于我可能想即时添加的任何内容,必须先在专栏中写下非常不方便。

请注意,简单的apply 在这里不起作用,因为它不知道如何理解每个组可能大小不同的结果数组。

【问题讨论】:

  • 没有。请参阅 Pandas 库。
  • 这和我刚要问的问题出奇的一样!奇怪!

标签: python group-by transform dataframe pandas


【解决方案1】:

apply 遇到了什么问题?它在这里适用于这个玩具示例,并且组长度不同:

In [82]: df
Out[82]: 
   X         Y
0  0 -0.631214
1  0  0.783142
2  0  0.526045
3  1 -1.750058
4  1  1.163868
5  1  1.625538
6  1  0.076105
7  2  0.183492
8  2  0.541400
9  2 -0.672809

In [83]: def func(x):
   ....:     x['NewCol'] = np.nan
   ....:     return x
   ....: 

In [84]: df.groupby('X').apply(func)
Out[84]: 
   X         Y  NewCol
0  0 -0.631214     NaN
1  0  0.783142     NaN
2  0  0.526045     NaN
3  1 -1.750058     NaN
4  1  1.163868     NaN
5  1  1.625538     NaN
6  1  0.076105     NaN
7  2  0.183492     NaN
8  2  0.541400     NaN
9  2 -0.672809     NaN

【讨论】:

  • 它应该足够聪明,可以知道将新列的特定于组的部分自动粘贴到哪里。基本上,df["NewCol"] = df.groupby("X").apply(some_inline_func) 的语法应该与上面定义 some_inline_func 的方式类似。
  • 怎么样:dfrm['A_xtile'] = dfrm.groupby('C').A.transform(mark_quintiles, [0.2, 0.4, 0.6, 0.8, 1.0])? (好像可以在最新的pandas版本上运行,旧的没试过)
  • 这太棒了,值得加入pandas Split-Apply-Combine doc 我刚刚花了 4 天时间尝试 set_index、sort_index 等,将 groupby 结果重新插入到其源数据帧中。
  • @ChangShe 当我尝试df.groupby('X').apply(func) 时,结果数据帧现在由它执行的分组索引。你的怎么不是这样的?
  • @guy 在groupby 中添加group_keys=False 作为参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-21
  • 1970-01-01
  • 2012-08-25
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
相关资源
最近更新 更多