2017-08-16 80 views
1

我有以下结构例如大熊猫数据帧:大熊猫集团通过具有多种功能的应用

id,sex,age,rank,skill 
1,M,9,1,A 
1,M,8,2,G 
1,M,10,3,F 
2,F,10,3,M 
2,F,8,4,W 
2,F,6,4,O 
3,M,5,1,Q 
3,M,4,3,N 
3,M,9,4,Y 

凡GROUPBY后,我的期望输出/应用操作的数据帧是:

id,sex,age,rank,skill 
1,M,8,1,A 
2,F,6,3,M 
3,M,4,1,Q 

换句话说,我正在寻找由ID字段组成的字段,性场不变,年龄值的min(),rank值的min(),以及出现在min()等级值。

我知道多个agg函数可以通过字典传递给groupby,但是它如何处理常量或取决于组中另一个字段中函数结果的值,我不明白。

回答

2

在你的预期了的说,它是rankmin,但在你的解释,你提到这是你max

我的答案基地预计输出

df.groupby(['id','sex'],as_index=False).agg({'age':'min','rank':'min'}).\ 
merge(df.drop('age',1),on=['id','sex','rank'],how='left') 

Out[931]: 
    id sex age rank skill 
0 1 M 8  1  A 
1 2 F 6  3  M 
2 3 M 4  1  Q 
+0

这绝对是最好的方法。我发现kbball的重组版本更容易遵循。 – Pylander

+0

@Pylander很高兴它的帮助〜也一步一步总是很好的遵循,将在我以后的职位考虑。谢谢〜美好的一天 – Wen

1

对于具有常数值的列,您有几个选项:第一个,最后一个等等。对于与最高(或您的示例中的最小值)等级值对应的技能值,您需要使用idxmin。对于idxmin的工作,技能应该是索引,以便第一步将其设置为索引。

df.set_index('skill').groupby('id').agg({'sex': 'first', 
             'age': 'min', 
             'rank': ['min', 'idxmin']}) 
Out: 
    sex age rank  
    first min min idxmin 
id      
1  M 8 1  A 
2  F 6 3  M 
3  M 4 1  Q 
+0

感谢您解释如何集成idxmin。我也纠正排名值min(),我的困惑。还有一个问题,将idxmin输出重命名为原始字段名称很简单吗?我很可能在现实世界的例子中需要设置很多列。 – Pylander

+0

@Pylander由于该函数在等级列上被调用,因此该名称将与该列相关联。尽管重命名多重索引真的很痛苦。我会从头开始构建一个扁平列表。温氏的方法可能更适合可能? – ayhan

+0

是的,我最终看到这种方法的局限性不幸。非常干净的格式,尽管我喜欢。 Wen的答案由kbball重新格式化,最终效果最好。 – Pylander

1

+1文。

煤矿有几个步骤,但它同样的想法,也许更容易阅读,如果你不遵循:

func = {'sex': 'min', 'age': 'min', 'rank': 'min'} 

df_agg = df.groupby('id').agg(func) 
df_agg = df_agg.reset_index() 

df = df.drop('age', 1) 
df = pd.merge(df_agg, df, on = ['id', 'sex', 'rank']) 

设置要应用到每一列的聚合。然后按id,使用agg。您需要在此时重置索引,否则您将无法在下一步执行合并,因为id将被视为索引。

df仍然存储您的原始数据帧。从df下降的年龄,因为您只需要最小化的年龄,存储在df_agg中。然后在你期望匹配的列上执行合并:id,性别和等级。你正在合并等级,为正确的行程提供正确的技能。

+0

我必须给予温的功劳,但我正在使用你的改编解决方案结束。谢谢! – Pylander