ely*_*ely 30 python group-by transform dataframe pandas
我想在我的数据中标记一些分位数,并且对于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,))})
Run Code Online (Sandbox Code Playgroud)
让我们说我编写自己的函数来计算数组中每个元素的五分位数.我有自己的功能,但是例如只需要参考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.
Run Code Online (Sandbox Code Playgroud)
现在,真正的问题是如何使用transform
向数据添加新列.像这样的东西:
def transformXtiles(dataFrame, inputColumnName, newColumnName, breaks):
dataFrame[newColumnName] = mark_quintiles(dataFrame[inputColumnName].values,
breaks)
return dataFrame
Run Code Online (Sandbox Code Playgroud)
然后:
dfrm.groupby("C").transform(lambda x: transformXtiles(x, "A", "A_xtile", [0.2, 0.4, 0.6, 0.8, 1.0]))
Run Code Online (Sandbox Code Playgroud)
问题是上面的代码不会添加新列"A_xtile".它只是保持我的数据框不变.如果我首先添加一个充满虚拟值的列,例如NaN,称为"A_xtile",那么它会成功覆盖此列以包含正确的五分位标记.
但是,必须首先在列中写入我可能想要添加的类似内容非常不方便.
请注意,简单apply
在这里不起作用,因为它不知道如何理解每个组可能不同大小的结果数组.
Cha*_*She 37
你遇到了什么问题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
Run Code Online (Sandbox Code Playgroud)