Jas*_*oal 7 python function dataframe pandas pandas-groupby
我有一个DataFrame如下所示:
df = {'col_1': [1,2,3,4,5,6,7,8,9,10],
'col_2': [1,2,3,4,5,6,7,8,9,10],
'col_3':['A','A','A','A','A','B','B','B','B','B']}
df = pd.DataFrame(df)
Run Code Online (Sandbox Code Playgroud)
虽然我使用的真实数据有数百列,但我想使用不同的函数来操作这些列min,max 以及自定义函数,如:
def dist(x):
return max(x) - min(x)
def HHI(x):
ss = sum([s**2 for s in x])
return ss
Run Code Online (Sandbox Code Playgroud)
我想要的功能如下:
def myfunc(cols,fun):
return df.groupby('col_3')[[cols]].transform(lambda x: fun)
# which allow me to do something like:
df[['min_' + s for s in cols]] = myfunc(cols, min)
df[['max_' + s for s in cols]] = myfunc(cols, max)
df[['dist_' + s for s in cols]] = myfunc(cols, dist)
Run Code Online (Sandbox Code Playgroud)
这在Python中是否可行(我的猜测是'是')?
那如果是的话呢?
编辑======关于自定义功能的名称=======
根据jpp我的解决方案,我所问的是可能的,至少对于bulit-in功能,更多的工作需要考虑自定义功能.
一个可行的解决方案,
temp = df.copy()
for func in ['HHI','DIST'] :
print(func)
temp[[ func + s for s in cols]] = df.pipe(myfunc,cols,eval(func))
Run Code Online (Sandbox Code Playgroud)
这里的关键是使用eval函数将字符串表达式转换为函数.但是,可能有更好的方法来做到这一点,期待看到.
编辑======每个jpp关于自定义函数名称的评论=======
jpp的注释直接提供函数名称myfun是基于我的测试有效的,但是,基于的新列名func将会是:有些<function HHI at 0x00000194460019D8>不可读的,修改是temp[[ str(func.__name__) + s for s in cols]],希望这会有助于后来遇到这个问题的人.
这是使用的一种方法pd.DataFrame.pipe。
在 Python 中,一切都是对象,并且无需类型检查即可传递。其理念是“不要检查它是否有效,只需尝试一下......”。因此,您可以将字符串或函数传递给myfunc,而不会产生transform任何有害的副作用。
def myfunc(df, cols, fun):
return df.groupby('col_3')[cols].transform(fun)
cols = ['col_1', 'col_2']
df[[f'min_{s}' for s in cols]] = df.pipe(myfunc, cols, 'min')
df[[f'max_{s}' for s in cols]] = df.pipe(myfunc, cols, 'max')
df[[f'dist_{s}' s in cols]] = df.pipe(myfunc, cols, lambda x: x.max() - x.min())
Run Code Online (Sandbox Code Playgroud)
结果:
print(df)
col_1 col_2 col_3 min_col_1 min_col_2 max_col_1 max_col_2 dist_col_1 \
0 1 1 A 1 1 5 5 4
1 2 2 A 1 1 5 5 4
2 3 3 A 1 1 5 5 4
3 4 4 A 1 1 5 5 4
4 5 5 A 1 1 5 5 4
5 6 6 B 6 6 10 10 4
6 7 7 B 6 6 10 10 4
7 8 8 B 6 6 10 10 4
8 9 9 B 6 6 10 10 4
9 10 10 B 6 6 10 10 4
dist_col_2
0 4
1 4
2 4
3 4
4 4
5 4
6 4
7 4
8 4
9 4
Run Code Online (Sandbox Code Playgroud)