抱歉读了很久,这个问题实际上比看起来要短得多。
谁能解释一下如何使用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
显然,我们得到了一组带有键(列A
值(B
列的值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
这类似于另一列的第 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
组成(,类似于reduce的操作?
> pandas 正在试验输入(逐个系列或整个数据帧(,看看是否可以更有效地应用该函数。文档字符串中的注释:
当前的实现对 f 提出了三个要求:
- f 必须返回一个值,该值要么与输入子帧的形状相同,要么可以广播到输入子帧的形状。 为 例如,f 返回一个标量,它将被广播为具有相同的标量 形状作为输入子框架。
- 如果这是数据帧,则 f 必须支持子帧中的逐列应用程序。如果 f 也支持应用于整个 子帧,然后使用从第二个块开始的快速路径。
- f 不得使组发生突变。不支持突变,可能会产生意外结果。
对同一函数的第二次调用也是关于找到更快的路径。您会看到与应用相同的行为:
在当前实现中,在第一个应用调用 func 两次 列/行,以确定它是否可以采用快速或慢速代码路径。 如果 func 有副作用,这可能会导致意外行为,因为它们 将对第一列/第一行生效两次。