python pandas groupby/apply: 到底传递给应用函数的是什么?
python pandas groupby/apply: what exactly is passed to the apply function?
Python 这里是新手。我试图了解 pandas groupby 和 apply 方法的工作原理。我找到了 this 简单示例,我将其粘贴在下面:
import pandas as pd
ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}
df = pd.DataFrame(ipl_data)
数据帧 df
如下所示:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
2 Devils 2 2014 863
3 Devils 3 2015 673
4 Kings 3 2014 741
5 kings 4 2015 812
6 Kings 1 2016 756
7 Kings 1 2017 788
8 Riders 2 2016 694
9 Royals 4 2014 701
10 Royals 1 2015 804
11 Riders 2 2017 690
到目前为止,还不错。然后我想 t运行sform 我的数据,以便从每组团队中我只保留 Points 列中的第一个元素。首先检查 df['Points'][0]
确实给了我 df
的第一个 Points
元素,我试过这个:
df.groupby('Team').apply(lambda x : x['Points'][0])
认为 lambda
函数的参数 x
是另一个 pandas 数据帧。但是,python 会产生错误:
File "pandas/_libs/index.pyx", line 81, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 89, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 132, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/hashtable_class_helper.pxi", line 987, in pandas._libs.hashtable.Int64HashTable.get_item
File "pandas/_libs/hashtable_class_helper.pxi", line 993, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 0
这似乎与哈希表有关,但我不明白为什么。然后我想也许传递给 lambda
的不是数据帧,所以我 运行 这个:
df.groupby('Team').apply(lambda x : (type(x), x.shape))
输出:
Team
Devils (<class 'pandas.core.frame.DataFrame'>, (2, 4))
Kings (<class 'pandas.core.frame.DataFrame'>, (3, 4))
Riders (<class 'pandas.core.frame.DataFrame'>, (4, 4))
Royals (<class 'pandas.core.frame.DataFrame'>, (2, 4))
kings (<class 'pandas.core.frame.DataFrame'>, (1, 4))
dtype: object
IIUC 表明 lambda
的参数确实是一个 pandas 数据框,其中包含每个团队的 df
.
子集
我知道我可以通过 运行:
得到想要的结果
df.groupby('Team').apply(lambda x : x['Points'].iloc[0])
我只是想了解为什么 df['Points'][0]
有效而 x['Points'][0]
在应用函数中无效。感谢阅读!
Apply 函数获取每一行并处理数据,因此 Apply 确实不理解您传递给它的索引(如 [0]),因此出现错误。它适用于 df,因为索引仍然适用于 df。
您可以尝试类似的方法来为每个团队获得第一分。
df.drop_duplicates(subset=['Team'])
输出:
Team Rank Year Points
0 Riders 1 2014 876
2 Devils 2 2014 863
4 Kings 3 2014 741
5 kings 4 2015 812
9 Royals 4 2014 701
如果您需要保留 max/min 点行,您可以在删除 duplicates.Hope 之前对 df 进行排序,这有帮助。
当您调用 df.groupby('Team').apply(lambda x: ...)
时,您实际上是在按团队切碎数据帧并将每个块传递给 lambda 函数:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
8 Riders 2 2016 694
11 Riders 2 2017 690
------------------------------
2 Devils 2 2014 863
3 Devils 3 2015 673
------------------------------
4 Kings 3 2014 741
6 Kings 1 2016 756
7 Kings 1 2017 788
------------------------------
5 kings 4 2015 812
------------------------------
9 Royals 4 2014 701
10 Royals 1 2015 804
df['Points'][0]
有效,因为您将 pandas 告诉 "get the value at label 0 of the Points
series",它存在。
.apply(lambda x: x['Points'][0])
不起作用,因为只有 1 个块 (Riders
) 的标签为 0。因此您会遇到密钥错误。
话虽如此,apply
是通用的,因此与内置的矢量化聚合函数相比它非常慢。您可以使用 first
:
df.groupby('Team')['Points'].first()
题目问题,
agroupby = df.groupby(...)
help( agroupby.apply ) # or in IPython xx.<tab> for help( xx )
apply(func, *args, **kwargs) method of pandas.core.groupby.generic.DataFrameGroupBy instance
Apply function func
group-wise and combine the results together.
The function passed to apply
must take a dataframe as its first
argument and return a DataFrame, Series or scalar. apply
will
then take care of combining the results back together into a single
dataframe or series.
Python 这里是新手。我试图了解 pandas groupby 和 apply 方法的工作原理。我找到了 this 简单示例,我将其粘贴在下面:
import pandas as pd
ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}
df = pd.DataFrame(ipl_data)
数据帧 df
如下所示:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
2 Devils 2 2014 863
3 Devils 3 2015 673
4 Kings 3 2014 741
5 kings 4 2015 812
6 Kings 1 2016 756
7 Kings 1 2017 788
8 Riders 2 2016 694
9 Royals 4 2014 701
10 Royals 1 2015 804
11 Riders 2 2017 690
到目前为止,还不错。然后我想 t运行sform 我的数据,以便从每组团队中我只保留 Points 列中的第一个元素。首先检查 df['Points'][0]
确实给了我 df
的第一个 Points
元素,我试过这个:
df.groupby('Team').apply(lambda x : x['Points'][0])
认为 lambda
函数的参数 x
是另一个 pandas 数据帧。但是,python 会产生错误:
File "pandas/_libs/index.pyx", line 81, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 89, in pandas._libs.index.IndexEngine.get_value
File "pandas/_libs/index.pyx", line 132, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/hashtable_class_helper.pxi", line 987, in pandas._libs.hashtable.Int64HashTable.get_item
File "pandas/_libs/hashtable_class_helper.pxi", line 993, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 0
这似乎与哈希表有关,但我不明白为什么。然后我想也许传递给 lambda
的不是数据帧,所以我 运行 这个:
df.groupby('Team').apply(lambda x : (type(x), x.shape))
输出:
Team
Devils (<class 'pandas.core.frame.DataFrame'>, (2, 4))
Kings (<class 'pandas.core.frame.DataFrame'>, (3, 4))
Riders (<class 'pandas.core.frame.DataFrame'>, (4, 4))
Royals (<class 'pandas.core.frame.DataFrame'>, (2, 4))
kings (<class 'pandas.core.frame.DataFrame'>, (1, 4))
dtype: object
IIUC 表明 lambda
的参数确实是一个 pandas 数据框,其中包含每个团队的 df
.
我知道我可以通过 运行:
得到想要的结果df.groupby('Team').apply(lambda x : x['Points'].iloc[0])
我只是想了解为什么 df['Points'][0]
有效而 x['Points'][0]
在应用函数中无效。感谢阅读!
Apply 函数获取每一行并处理数据,因此 Apply 确实不理解您传递给它的索引(如 [0]),因此出现错误。它适用于 df,因为索引仍然适用于 df。
您可以尝试类似的方法来为每个团队获得第一分。
df.drop_duplicates(subset=['Team'])
输出:
Team Rank Year Points
0 Riders 1 2014 876
2 Devils 2 2014 863
4 Kings 3 2014 741
5 kings 4 2015 812
9 Royals 4 2014 701
如果您需要保留 max/min 点行,您可以在删除 duplicates.Hope 之前对 df 进行排序,这有帮助。
当您调用 df.groupby('Team').apply(lambda x: ...)
时,您实际上是在按团队切碎数据帧并将每个块传递给 lambda 函数:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
8 Riders 2 2016 694
11 Riders 2 2017 690
------------------------------
2 Devils 2 2014 863
3 Devils 3 2015 673
------------------------------
4 Kings 3 2014 741
6 Kings 1 2016 756
7 Kings 1 2017 788
------------------------------
5 kings 4 2015 812
------------------------------
9 Royals 4 2014 701
10 Royals 1 2015 804
df['Points'][0]
有效,因为您将 pandas 告诉 "get the value at label 0 of the Points
series",它存在。
.apply(lambda x: x['Points'][0])
不起作用,因为只有 1 个块 (Riders
) 的标签为 0。因此您会遇到密钥错误。
话虽如此,apply
是通用的,因此与内置的矢量化聚合函数相比它非常慢。您可以使用 first
:
df.groupby('Team')['Points'].first()
题目问题,
agroupby = df.groupby(...)
help( agroupby.apply ) # or in IPython xx.<tab> for help( xx )
apply(func, *args, **kwargs) method of pandas.core.groupby.generic.DataFrameGroupBy instance
Apply function
func
group-wise and combine the results together.The function passed to
apply
must take a dataframe as its first argument and return a DataFrame, Series or scalar.apply
will then take care of combining the results back together into a single dataframe or series.