【发布时间】:2017-05-19 11:43:51
【问题描述】:
我不明白为什么apply 和transform 在同一个数据帧上调用时会返回不同的数据类型。我之前向自己解释这两个函数的方式类似于“apply 折叠数据,transform 与 apply 执行完全相同的操作,但保留原始索引并且不会折叠。”请考虑以下事项。
df = pd.DataFrame({'id': [1,1,1,2,2,2,2,3,3,4],
'cat': [1,1,0,0,1,0,0,0,0,1]})
让我们找出那些在cat 列中有非零条目的ids。
>>> df.groupby('id')['cat'].apply(lambda x: (x == 1).any())
id
1 True
2 True
3 False
4 True
Name: cat, dtype: bool
太好了。但是,如果我们想创建一个指标列,我们可以执行以下操作。
>>> df.groupby('id')['cat'].transform(lambda x: (x == 1).any())
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 0
8 0
9 1
Name: cat, dtype: int64
我不明白为什么 dtype 现在是 int64 而不是 any() 函数返回的布尔值。
当我将原始数据框更改为包含一些布尔值(注意零仍然存在)时,转换方法会在 object 列中返回布尔值。这对我来说是一个额外的谜,因为所有值都是布尔值,但它被列为 object 显然与整数和布尔值的原始混合类型列的 dtype 匹配。
df = pd.DataFrame({'id': [1,1,1,2,2,2,2,3,3,4],
'cat': [True,True,0,0,True,0,0,0,0,True]})
>>> df.groupby('id')['cat'].transform(lambda x: (x == 1).any())
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 False
8 False
9 True
Name: cat, dtype: object
但是,当我使用所有布尔值时,转换函数会返回一个布尔列。
df = pd.DataFrame({'id': [1,1,1,2,2,2,2,3,3,4],
'cat': [True,True,False,False,True,False,False,False,False,True]})
>>> df.groupby('id')['cat'].transform(lambda x: (x == 1).any())
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 False
8 False
9 True
Name: cat, dtype: bool
使用我敏锐的模式识别技能,结果列的dtype 似乎与原始列的相同。我将不胜感激有关为什么会发生这种情况或 transform 函数中发生的事情的任何提示。干杯。
【问题讨论】:
-
apply不会折叠数据。apply很灵活,可以返回任意大小的系列或数据帧。transform始终保留每个组的行数。transform还将每个单独的列作为一个系列发送给调用函数。apply将整个数据帧发送给调用函数。 -
啊哈!谢谢@piRSquared。在阅读该评论并查看源代码后,我想我更好地理解了为什么会发生这种情况。
标签: python pandas transform apply