在 groupby.transform 中传递多个列

198 阅读2分钟

在使用 Pandas 的 groupby.transform 时,常会遇到需要同时使用多个列的值作为参数来转换数据的情况。然而,直接传递多个列时却无法正常工作。例如,以下代码试图计算每一组中列 a 和列 b 的均值之差乘以列 c 的值,并将其作为新列 f 的值:

huake_00257_.jpg

import numpy as np
import pandas as pd

people = pd.DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
key = ['one', 'two', 'one', 'two', 'one']

Grouped = people.groupby(key)

def TransFunc(col1, col2, col3):
    return col1.mean() - col2.mean() * col3

Grouped.f.transform(TransFunc(Grouped['a'], Grouped['b'], Grouped['c']))

这样做却会报错,提示无法将列 f 转换为浮点数。这是因为 groupby.transform 只能处理一个列,而 TransFunc 函数却需要三个列作为参数。

2、解决方案

方法 1:使用 apply() 方法

为了解决这个问题,可以使用 apply() 方法。apply() 方法可以将一个函数应用于 DataFrame 中的每一行或每一列,从而达到转换数据的目的。在 apply() 方法中,可以使用 lambda 表达式来实现对多个列值的处理。例如,以下代码使用 apply() 方法来计算新列 f 的值:

import numpy as np
import pandas as pd

people2 = pd.DataFrame(np.random.randn(5, 5), 
                      columns=['a', 'b', 'c', 'd', 'e'], 
                      index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
key = ['one', 'two', 'one', 'two', 'one']

Grouped = people2.groupby(key)

def f(df):
    df["f"] = (df.a.mean() - df.b.mean())*df.c
    return df

people2 = Grouped.apply(f)
print people2

这样就可以正确地计算出新列 f 的值。

方法 2:使用 lambda 表达式和 groupby.transform() 方法

如果您想使用 groupby.transform() 方法来实现同样的功能,可以使用 lambda 表达式来将多个列的值传递给函数。例如,以下代码使用 lambda 表达式来计算新列 f 的值:

import numpy as np
import pandas as pd

people2 = pd.DataFrame(np.random.randn(5, 5), 
                      columns=['a', 'b', 'c', 'd', 'e'], 
                      index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
key = ['one', 'two', 'one', 'two', 'one']

Grouped = people2.groupby(key)

def f(a, b, c, **kw):
    return (a.mean() - b.mean())*c

people2["f"] = Grouped.apply(lambda df:f(**df))
print people2

这样也可以正确地计算出新列 f 的值。

方法 3:使用自定义函数和 groupby.transform() 方法

如果您想使用自定义函数来实现同样的功能,可以使用 groupby.transform() 方法来将多个列的值传递给函数。例如,以下代码使用自定义函数来计算新列 f 的值:

import numpy as np
import pandas as pd

people2 = pd.DataFrame(np.random.randn(5, 5), 
                      columns=['a', 'b', 'c', 'd', 'e'], 
                      index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
key = ['one', 'two', 'one', 'two', 'one']

Grouped = people2.groupby(key)

def TransFunc(col1, col2, col3):
    return col1.mean() - col2.mean() * col3

people2["f"] = Grouped.transform(lambda df: TransFunc(df['a'], df['b'], df['c']))

这样也可以正确地计算出新列 f 的值。

通过以上三种方法,您都可以将多个列的值传递给 groupby.transform,从而实现对数据的多列转换。