看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Pandas 的 transform() 方法可以调用一个函数,在每个组上生成一个相似的索引数据帧,并返回一个数据帧,该数据帧的索引与原始对象的索引相同,并填充转换后的值。Series、DataFrame、DataFrameGroupBy、SeriesGroupBy、Resampler 均可以使用。它可以实现类似 SQL 中的窗口函数的功能。
transform() 方法返回与原始对象索引相同(大小相同)的对象。此 API 允许您同时提供多个操作,而不是逐个操作。它的 API 与 .agg
API 非常相似。
参数:
*args
:要传递给 func 的位置参数。**kwargs
:要传递给func的关键字参数。返回:
异常抛出:
简单示例如下:
df = pd.DataFrame({'A': range(3),
'B': range(-2, 1)})
df
'''
A B
0 0 -2
1 1 -1
2 2 0
'''
df.transform(lambda x: x + 1)
'''
A B
0 1 -1
1 2 0
2 3 1
'''
接下来讲解更多用法。转移整个帧,transform 允许输入函数为:NumPy 函数、字符串函数名或用户定义函数。
# 以下方法结果相同
df.transform(np.abs)
df.transform("abs")
df.transform(lambda x: x.abs())
'''
A B
0 0 2
1 1 1
2 2 0
'''
# 以上相当于
np.abs(df)
传递多个函数将产生一个列多索引数据帧,第一级将是原始框架列名,第二级是转换函数的名称。
df.transform([np.abs, lambda x: x + 1])
'''
A B
absolute <lambda> absolute <lambda>
0 0 1 2 -1
1 1 2 1 0
2 2 3 0 1
'''
传递函数的 dict 将允许对每列进行选择性转换。
df.transform({"A": np.abs, "B": lambda x: x + 1})
'''
A B
0 0 -1
1 1 0
2 2 1
'''
传递列表的 dict 将生成具有这些选择性转换的多索引数据帧。
df.transform({"A": np.abs, "B": [lambda x: x + 1, "cumsum"]})
'''
A B
absolute <lambda> cumsum
0 0 -1 -2
1 1 0 -3
2 2 1 -3
'''
可以为每行指定不同的计算方法:
df.transform({0:abs,
1: np.log,
2:lambda x:x+2}, axis=1)
'''
A B
0 0.0 2.0
1 0.0 NaN
2 4.0 2.0
'''
Series 调用 transform 语法如下:
Series.transform(func, axis=0, *args, **kwargs)
参数作用与 DataFrame 的相同,其中axis:{0 or ‘index’}
,默认是列,是与 DataFrame 兼容所需的参数。返回的是一个 Series,必须与自身长度相同的序列
本方法在 Series 调用函数(func),函数传入 Series 自身,返回一个具有与自身相同的轴长度的 Series。
生成的序列必须与输入序列具有相同的长度,也可以提供多个输入函数:
s = pd.Series(range(3))
s
'''
0 0
1 1
2 2
dtype: int64
'''
# 对每个值加 5
s.transform(lambda x: x+5)
'''
0 5
1 6
2 7
dtype: int64
'''
# 累加
s.transform(pd.Series.cumsum)
'''
0 0
1 1
2 3
dtype: int64
'''
# 传入两个函数
s.transform([np.sqrt, np.exp])
'''
sqrt exp
0 0.000000 1.000000
1 1.000000 2.718282
2 1.414214 7.389056
'''
调用函数,在每个组上生成一个相似的索引 DataFrame,并返回一个 DataFrame,该 DataFrame 的索引与原始对象的索引相同,并填充转换后的值。
DataFrameGroupBy.transform(func, *args, engine=None,
engine_kwargs=None, **kwargs)
参数:
*args
:要传递给func的位置参数{'nopython': True, 'nogil': False, 'parallel': False}
,并将应用于函数**kwargs
:要传递到 func 的关键字参数返回:
一个简单的例子:
df = pd.DataFrame({
"Date": [
"2015-05-08", "2015-05-07", "2015-05-06", "2015-05-05",
"2015-05-08", "2015-05-07", "2015-05-06", "2015-05-05"],
"Data": [5, 8, 6, 1, 50, 100, 60, 120],
})
df
'''
Date Data
0 2015-05-08 5
1 2015-05-07 8
2 2015-05-06 6
3 2015-05-05 1
4 2015-05-08 50
5 2015-05-07 100
6 2015-05-06 60
7 2015-05-05 120
'''
# 按相同日期分组对应行的平均值
df.groupby('Date').transform('sum')
'''
Data
0 55
1 108
2 66
3 121
4 55
5 108
6 66
7 121
'''
每个组都被赋予“name”属性,以防您需要知道正在处理的组。目前的实施对f提出了三个要求:
使用 engine='numba' 时,内部将不会出现“后退”行为。组数据和组索引将作为 numpy 数组传递给 JITed 用户定义函数,并且不会尝试其他执行。
在版本 1.3.0 中更改:生成的数据类型将反映传递的 func 的返回值。
新增加一列,反映每组的个数。
df = pd.DataFrame({
"c": [1, 1, 1, 2, 2, 2, 2],
"type": ["m", "n", "o", "m", "m", "n", "n"]
})
df
'''
c type
0 1 m
1 1 n
2 1 o
3 2 m
4 2 m
5 2 n
6 2 n
'''
df['size'] = df.groupby('c')['type'].transform(len)
df
'''
c type size
0 1 m 3
1 1 n 3
2 1 o 3
3 2 m 4
4 2 m 4
5 2 n 4
6 2 n 4
'''
我们利用教程的 team 数据集,实现一个每组同学在自己组的平均分排名的需求。先对数据增加平均分,然后进行分组,再利用 transform 给每个同学增加一个在组内的排名序号,完整代码是(为了方便演示,我们筛选每组的前两名):
(
df.assign(total=df.select_dtypes('number').mean(1))
.assign(rk=(lambda d: d.groupby('team')
.total
.transform(lambda x: x.rank(ascending=False).astype(int)))
)
.loc[lambda x: x.r<=2]
)
'''
name team Q1 Q2 Q3 Q4 total rk
3 Eorge C 93 96 71 78 84.50 1
12 Archie C 83 89 59 68 74.75 2
31 Joseph E 67 87 87 93 83.50 1
36 Jaxon E 88 98 19 98 75.75 2
42 Dylan A 86 87 65 20 64.50 2
50 Jenson B 66 77 88 74 76.25 1
57 Albie1 D 79 82 56 96 78.25 1
64 Harvey2 B 43 76 87 90 74.00 2
72 Luke6 D 15 97 95 99 76.50 2
75 Stanley A 69 71 39 97 69.00 1
'''
Series 的 GroupBy 和 DataFrame 的 GroupBy 类似,它返回的是一个相同长度的 Series。在些就不过多多介绍。
语法为:
Resampler.transform(fun, *args, **kwargs)
它调用函数,在每个组上生成一个类似的索引序列,并返回一个带有转换值的序列。fun 适用于每一组,应返回具有相同索引的序列。
如:
resampled.transform(lambda x: (x - x.mean()) / x.std())
关于 和 agg() 的区别。aggregation 会返回数据的缩减版本,而 transformation 能返回完整数据的某一变换版本供我们重组。这样的 transformation,输出的形状和输入一致。一个常见的例子是通过减去分组平均值来居中数据。
关于 Pandas groupby apply 和 transform 区别可以 访问。
总结一下,可以调用 transform()
的对象有以下对象有:
更新时间:2022-04-30 19:31:19 标签:pandas filter 转换