很抱歉,这个问题实际上比看起来的要短得多。
谁能解释pandas.core.groupby.groupby.DataFrameGroupBy.transorm
的函数类型参数是如何使用的?
我编写了此代码段,以找出将哪些参数输入到函数中
def printer(x): print(''); print(type(x)); print(x); return x
df = pd.DataFrame({'A': [1,1,2], 'B':[3,4,5], 'C':[6,7,8]})
print('initial dataframe:', df, '\n===TRANSFORM LOG BEGIN===', sep='\n')
df2 = df.groupby('A').transform(printer)
print('\n===TRANSFORM LOG END===', 'final dataframe:', df2, sep='\n')
输出为(分成多个块)
initial dataframe:
A B C
0 1 3 6
1 1 4 7
2 2 5 8
好的,继续
===TRANSFORM LOG BEGIN===
<class 'pandas.core.series.Series'>
0 3
1 4
Name: B, dtype: int64
显然,我们为B
列提供了一组带有键(列A
值)1
的值。继续
3。
<class 'pandas.core.series.Series'>
0 3
1 4
Name: B, dtype: int64
??。相同的Series
对象传递了两次。我可以想象的唯一理由是,有两行,列A
等于1
,因此对于每次出现这样的行,我们都会重新计算transforming
函数。似乎很奇怪且效率低下,很难做到。
4。
<class 'pandas.core.series.Series'>
0 6
1 7
Name: C, dtype: int64
类似于p.2中的另一列
5。
<class 'pandas.core.frame.DataFrame'>
B C
0 3 6
1 4 7
为什么没有p.3的对应对象?
6。
<class 'pandas.core.frame.DataFrame'>
B C
2 5 8
===TRANSFORM LOG END===
这是p.6的对应部分,但是为什么p.2没有另一个分组密钥?
7。
final dataframe:
B C
0 3 6
1 4 7
2 5 8
TLDR
除了奇怪的行为,要点是传递的函数同时获取Series
和DataFrame
对象作为参数。这是否意味着它(功能)必须同时尊重两种类型?由于该函数本质上是在相同值(Series
,然后是由这些Dataframe
组成的Series
)上多次调用,因此对转换类型有任何限制吗?< / p>
答案 0 :(得分:3)
pandas正在试验输入(逐个系列或整个DataFrame),以查看该功能是否可以更有效地应用。 docstring中的注释:
当前的实现对f施加了三个要求:
f必须返回一个具有与输入子帧相同的形状或可以广播为输入子帧的形状的值。对于 例如,f返回一个标量,它将被广播为具有相同的 形状作为输入子帧。
- 如果这是一个DataFrame,则f必须在子帧中逐列支持应用程序。如果f也支持整个应用程序 子帧,然后从第二个块开始使用快速路径。
- f不得变异群组。不支持突变,可能会产生意想不到的结果。
对同一函数的第二次调用也与寻找更快的路径有关。您看到与apply相同的行为:
在当前实现中,第一个应用调用func两次 列/行来决定采用快速还是慢速代码路径。 如果func具有副作用,则可能导致意外行为,因为它们具有 将对第一列/行生效两次。