apply和之间的两个主要区别transform
transform和
applygroupby方法之间有两个主要区别。
- 输入:
apply
将每个组的所有列作为Dataframe隐式传递给自定义函数。- 同时
transfor
m将每个组的每一列作为系列分别传递给自定义函数。 - 输出:
- 传递给的自定义函数
apply
可以返回标量,或者返回Series
或Dataframe
(或numpy数组,甚至是list
)。 - 传递给的自定义函数
transform
必须返回与group
长度相同的序列(一维Series
,数组或列表)。
因此,transform
一次只能处理一个Series
,而一次apply
可以处理整个Dataframe
。
检查自定义功能
检查传递给applyor的自定义函数的输入可能会很有帮助transform。
例子
让我们创建一些示例数据并检查组,以便你可以了解我在说什么:
import pandas as pddf = pd.Dataframe({'State':['Texas', 'Texas', 'Florida', 'Florida'], 'a':[4,5,1,3], 'b':[6,10,3,11]})df让我们创建一个简单的自定义函数,该函数打印出隐式传递的对象的类型,然后引发错误,以便可以停止执行。
def inspect(x): print(type(x)) raise
现在让我们将此函数传递给groupby apply和transformmethod,以查看传递给它的对象:
df.groupby('State').apply(inspect)<class 'pandas.core.frame.Dataframe'><class 'pandas.core.frame.Dataframe'>RuntimeError如你所见,Dataframe被传递到inspect函数中。你可能想知道为什么将Dataframe类型打印两次。熊猫两次参加第一组比赛。这样做是为了确定是否存在快速完成计算的方法。这是你不应该担心的次要细节。
现在,让我们用 transform
df.groupby('State').transform(inspect)<class 'pandas.core.series.Series'><class 'pandas.core.series.Series'>RuntimeError它传递了一个Series-一个完全不同的Pandas对象。
因此,一次transform只能使用一个系列。它不可能同时作用于两根色谱柱。因此,如果尝试a从b自定义函数中减去column ,则会出现错误transform。见下文:
def subtract_two(x): return x['a'] - x['b']df.groupby('State').transform(subtract_two)KeyError: ('a', 'occurred at index a')当熊猫试图找到
a不存在的
Series索引时,我们得到一个
KeyError。你可以通过完整
apply的
Dataframe来完成此操作:
df.groupby('State').apply(subtract_two)State Florida 2 -2 3 -8Texas 0 -2 1 -5dtype: int64输出是一个Series,并且保留了原始索引,因此有些混乱,但是我们可以访问所有列。
显示传递的熊猫对象
它可以在自定义函数中显示整个pandas对象,从而提供更多帮助,因此你可以确切地看到正在使用的对象。你可以使用print我喜欢使用模块中的display函数的语句,IPython.display以便在Jupyter笔记本中以HTML形式很好地输出Dataframe:
from IPython.display import displaydef subtract_two(x): display(x) return x['a'] - x['b']
变换必须返回与组大小相同的一维序列
另一个区别是transform必须返回与该组相同大小的一维序列。在此特定情况下,每个组都有两行,因此transform必须返回两行的序列。如果没有,则会引发错误:
def return_three(x): return np.array([1, 2, 3])df.groupby('State').transform(return_three)ValueError: transform must return a scalar value for each group该错误消息并不能真正描述问题。你必须返回与组相同长度的序列。因此,这样的功能将起作用:
def rand_group_len(x): return np.random.rand(len(x))df.groupby('State').transform(rand_group_len) a b0 0.962070 0.1514401 0.440956 0.7821762 0.642218 0.4832573 0.056047 0.238208返回单个标量对象也适用于 transform
如果仅从自定义函数返回单个标量,transform则将其用于组中的每一行:
def group_sum(x): return x.sum()df.groupby('State').transform(group_sum) a b0 9 161 9 162 4 143 4 14


