我有一个包含许多行和列的大型数据框,我需要将其中一个列'group'分组 这是一个小例子
group rank word
0 a 0.739631 entity
1 a 0.882556 physical_entity
2 b 0.588045 abstraction
3 b 0.640933 thing
4 c 0.726738 object
5 c 0.669280 whole
6 d 0.006574 congener
7 d 0.308684 living_thing
8 d 0.638631 organism
9 d 0.464244 benthos
基本上,我将应用一系列函数来创建新列并在组之后转换现有列,例如:
我想要实现的功能之一是top_word
,它为每个组选择排名最高的单词。所以它的输出将是一个unicode列:
group top_word
a physical_entity [0.88]
b thing [0.64]
c object [0.73]
d organism [0.63]
目前,我正在使用这种可怕的方法:
def top_word(tab):
first = tab.iloc[0]
res = '{} [{:.2f}]'.format(first['word'], first['rank'])
return [res]
def aggr(x, fns):
d = {key: fn(x) for key, fn in fns.iteritems()}
return pd.DataFrame(d)
fs = {'top_word': top_word}
T = T.sort('rank', ascending=False) #sort by rank then I only have to pick the first result in the aggfunc!
T = T.groupby('group', sort=False).apply(lambda x: aggr(x, fs))
T.index = T.index.droplevel(level=1)
给出(例如,由于随机数生成器导致的结果不同):
time taken: 0.0042 +- 0.0003 seconds
top_word
group
a entity [0.07]
b abstraction [0.84]
c object [0.92]
d congener [0.06]
我已经设计了这个方法,所以我可以随时应用我想要的任何功能。它需要保持这种灵活性,但它似乎太可怕了!有没有更有效的方法来做这样的事情?迭代群体+追加更好吗?
由于
答案 0 :(得分:1)
我认为首先是groupby
,然后是sort
每个group
,并使用.agg()
保留第一个观察结果:
In [192]:
print df
group rank word
0 a 0.739631 entity
1 a 0.882556 physical_entity
2 b 0.588045 abstraction
3 b 0.640933 thing
4 c 0.726738 object
5 c 0.669280 whole
6 d 0.006574 congener
7 d 0.308684 living_thing
8 d 0.638631 organism
9 d 0.464244 benthos
In [193]:
print df.groupby('group').agg(lambda x: sorted(x, reverse=True)[0])
rank word
group
a 0.882556 physical_entity
b 0.640933 thing
c 0.726738 whole
d 0.638631 organism
In [194]:
df_res = df.groupby('group').agg(lambda x: sorted(x, reverse=True)[0])
df_res.word+df_res['rank'].apply(lambda x: ' [%.2f]'%x)
Out[194]:
group
a physical_entity [0.88]
b thing [0.64]
c whole [0.73]
d organism [0.64]
dtype: object