我有以下玩具数据框(真正的玩具数据框有500k行):
df = pd.DataFrame({'size': list('SSMMMLS'),
'weight': [8, 10, 11, 1, 20, 14, 12],
'adult' : [False] * 5 + [True] * 2})
adult size weight
0 False S 8
1 False S 10
2 False M 11
3 False M 1
4 False M 20
5 True L 14
6 True S 12
并希望通过adult
分组,选择weight
最大的行,并在新列中size2
分配size
列值:
adult size size2 weight
0 False S S 8
1 False S S 10
2 False M S 11
3 False M S 1
4 False M S 20
5 True L L 14
6 True S L 12
我找到了this,但它对我不起作用
到目前为止,我有:
df.loc[:, 'size2'] = df.groupby('adult',as_index=True)['weight','size']
.transform(lambda x: x.ix[x['weight'].idxmax()]['size'])
答案 0 :(得分:3)
IIUC你可以使用merge
。我认为size2
中的第一个值是M
,因为最大weight
是20
。
df = pd.DataFrame({'size': list('SSMMMLS'),
'weight': [8, 10, 11, 1, 20, 14, 12],
'adult' : [False] * 5 + [True] * 2})
print df
adult size weight
0 False S 8
1 False S 10
2 False M 11
3 False M 1
4 False M 20
5 True L 14
6 True S 12
print df.groupby('adult').apply(lambda subf: subf['size'][subf['weight'].idxmax()]).reset_index(name='size2')
adult size2
0 False M
1 True L
print pd.merge(df, df.groupby('adult').apply(lambda subf: subf['size'][subf['weight'].idxmax()]).reset_index(name='size2'), on=['adult'])
adult size weight size2
0 False S 8 M
1 False S 10 M
2 False M 11 M
3 False M 1 M
4 False M 20 M
5 True L 14 L
6 True S 12 L
答案 1 :(得分:2)
使用您的数据框,更详细地了解@jazrael的答案:
df = pd.DataFrame({'size': list('SSMMMLS'),
'weight': [8, 10, 11, 1, 20, 14, 12],
'adult' : [False] * 5 + [True] * 2})
# adult size weight
# 0 False S 8
# 1 False S 10
# 2 False M 11
# 3 False M 1
# 4 False M 20
# 5 True L 14
# 6 True S 12
获取最大重量线的大小值:
def size4max_weight(subf):
""" Return size value for the max weight line """
return subf['size'][subf['weight'].idxmax()]
成人'成群结队将生成一个False的Serie,True作为索引值::
>>> size2_col = df.groupby('adult').apply(size4max_weight)
>>> type(size2_col), size2_col.index
(pandas.core.series.Series, Index([False, True], dtype='object', name=u'adult'))
使用reset_index
我们转换DataFrame ::
>>> size2_col = df.groupby('adult').apply(size4max_weight).reset_index(name='size2')
>>> size2_col
adult size2
0 False M
1 True L
>>>
成人' pd.merge
做到:
>>> pd.merge(df, size2_col, on=['adult'])
adult size weight size2
0 False S 8 M
1 False S 10 M
2 False M 11 M
3 False M 1 M
4 False M 20 M
5 True L 14 L
6 True S 12 L
答案 2 :(得分:1)
您可以将transform
与loc
和values
:
>>> df["size2"] = df["size"].loc[df.groupby("adult")["weight"].transform("idxmax")].values
>>> df
adult size weight size2
0 False S 8 M
1 False S 10 M
2 False M 11 M
3 False M 1 M
4 False M 20 M
5 True L 14 L
6 True S 12 L
一步一步,首先我们找到合适的指数:
>>> df.groupby("adult")["weight"].transform("idxmax")
0 4
1 4
2 4
3 4
4 4
5 5
6 5
dtype: int64
然后我们使用这些索引到size
列loc
:
>>> df["size"].loc[df.groupby("adult")["weight"].transform("idxmax")]
4 M
4 M
4 M
4 M
4 M
5 L
5 L
Name: size, dtype: object
最后我们采用.values
,以便在我们尝试分配时索引不会妨碍:
>>> df["size"].loc[df.groupby("adult")["weight"].transform("idxmax")].values
array(['M', 'M', 'M', 'M', 'M', 'L', 'L'], dtype=object)
>>> df["size2"] = df["size"].loc[df.groupby("adult")["weight"].transform("idxmax")].values
>>> df
adult size weight size2
0 False S 8 M
1 False S 10 M
2 False M 11 M
3 False M 1 M
4 False M 20 M
5 True L 14 L
6 True S 12 L