我有一个Dataframe table
,如下所示:
year name prop sex soundex
1880 John 0.081541 boy J500
1880 William 0.080511 boy W450
....
2008 Elianna 0.000127 girl E450
我尝试按table
对'year'
进行分组,并为每个组访问'name'
列中的选择索引。
我的代码如下(假设special_indices
已经定义):
def get_indices_func(x):
name = [x['name'].iloc[y] for y in special_indices]
return pd.Series(name)
table.groupby(by='year').apply(get_indices_func)
我收到以下错误:
/Users/***/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in get_value(self, series, key)
722 """
723 try:
--> 724 return self._engine.get_value(series, key)
725 except KeyError, e1:
726 if len(self) > 0 and self.inferred_type == 'integer':
KeyError: 1000
我做错了什么?我认为我并不真正了解申请(及其表兄弟,聚合和凝聚)的运作方式。如果有人能够解释,我会非常感激!
答案 0 :(得分:2)
我正在努力寻找每年最受欢迎的名字。有没有 聪明的方式去做这个?
有一种方法可以在不进行排序的情况下执行此操作:给定一个像这样的DataFrame:
In [5]: df
Out[5]:
year name prop sex soundex
0 1880 John 0.081541 boy J500
1 1880 William 0.080511 boy W450
2 2008 Elianna 0.000127 girl E450
[3 rows x 5 columns]
您可以按年份分组,隔离道具列,应用argmax
,然后使用loc
选择所需的行:
In [15]: df.loc[df.groupby('year')['prop'].apply(lambda x: x.argmax())]
Out[15]:
year name prop sex soundex
0 1880 John 0.081541 boy J500
2 2008 Elianna 0.000127 girl E450
[2 rows x 5 columns]
In [19]: df['name'].loc[df.groupby('year')['prop'].apply(lambda x: x.argmax())]
Out[19]:
0 John
2 Elianna
Name: name, dtype: object
请注意,argmax
和loc
的使用依赖于具有唯一索引的df
。如果DataFrame没有唯一索引,则需要首先使索引唯一:
df.reset_index()
请注意,argmax
是O(n)
操作,而排序是O(n log n)
。即使对于小型DataFrame,速度优势也很明显:
In [125]: %timeit df[['year', 'name']].loc[df.groupby('year')['prop'].apply(lambda x: x.argmax())]
1000 loops, best of 3: 1.07 ms per loop
In [126]: %timeit df.groupby('year').apply(lambda x: x.sort('prop', ascending=False).iloc[0]['name'])
100 loops, best of 3: 2.14 ms per loop
基准测试是在这个DataFrame上运行的:
In [131]: df
Out[131]:
year name prop sex soundex
0 2008 A 0.000027 girl E450
1 1880 John 0.081541 boy J500
2 2008 B 0.000027 girl E450
3 2008 Elianna 0.000127 girl E450
4 1880 William 0.080511 boy W450
5 2008 C 0.000027 girl E450
6 1880 D 0.080511 boy W450
[7 rows x 5 columns]
答案 1 :(得分:1)
尝试这样的事情:定义一个聚合函数,用prop对每组数据进行排序(为此你必须复制)。该函数返回该复制和排序数据的第一行(即具有最高的prop值)。将此函数传递给.agg
并按年份对数据进行分组。
def get_most_popular(x):
y = x.copy()
y.sort('prop')
return y.iloc[0]
df.groupby('year').agg(get_most_popular)
答案 2 :(得分:1)
另一种解决方案:
df.groupby('year').apply(lambda x: x.sort('prop', ascending=False).iloc[0]['name'])
这里发生了什么?
首先,与Woody一样,我们按正确的列分组。 apply()
将为该功能提供组级数据。相反,出于理解的目的,我本来可以写
define takeAGroupAndGiveBackMax(group):
# year level data: first sort it by prop, descending
group.sort('prop', ascending=False, inplace=True)
# now return value 'name' of the first entry
return group.iloc[0]['name']
# the following will give you a data set, indexed on whatever you grouped it by (here: year), and have a columns all the properties you return.
df.groupby('year').apply(takeAGroupAndGiveBackMax)
为了理解这些,您应该使用该功能。尝试返回多列,多行,您将看到apply()
返回给您的内容。它实际上是熊猫带给你的强大工具。