在带有 Groupby 的 Pandas 中:从以另一列为条件的列中分配一个值
Posted
技术标签:
【中文标题】在带有 Groupby 的 Pandas 中:从以另一列为条件的列中分配一个值【英文标题】:In Pandas with Groupby: assign a value from a column conditioned on another column 【发布时间】:2021-09-02 13:19:01 【问题描述】:我有一个这样的 DataFrame:
df = pd.DataFrame('col0': list('aabb'),
'col1': np.arange(4),
'col2': list('wxyz'),
'col3': np.nan)
col0 col1 col2 col3
0 a 0 w NaN
1 a 1 x NaN
2 b 2 y NaN
3 b 3 z NaN
我想将“col1”的最小值对应的“col2”的值分配给“col3”,按“col0”分组。预期输出:
col0 col1 col2 col3
0 a 0 w w
1 a 1 x w
2 b 2 y y
3 b 3 z y
如果不需要按 'col0' 分组,这会起作用:
df['col3'] = df[df['col1']==df['col1'].min()]['col2'].iloc[0]
col0 col1 col2 col3
0 a 0 w w
1 a 1 x w
2 b 2 y w
3 b 3 z w
同样,这是我使用 groupby/apply 的尝试,但没有按预期工作:
df['col3'] = df.groupby('col0').apply(lambda x: x[x['col1']==x['col1'].min()]['col2'].iloc[0])
col0 col1 col2 col3
0 a 0 w NaN
1 a 1 x NaN
2 b 2 y NaN
3 b 3 z NaN
【问题讨论】:
【参考方案1】:你可以通过变换idxmin
然后series.map
进行分组:
d = dict(zip(df['col1'],df['col2']))
df['col3'] = df['col3'].fillna(df.groupby("col0")['col1'].transform('idxmin').map(d))
print(df)
col0 col1 col2 col3
0 a 0 w w
1 a 1 x w
2 b 2 y y
3 b 3 z y
【讨论】:
【参考方案2】:另一个transform
ing 与idxmin
和loc
:
df["col3"] = df.groupby("col0").col1.transform(lambda x: df.loc[x.idxmin(), "col2"])
得到
col0 col1 col2 col3
0 a 0 w w
1 a 1 x w
2 b 2 y y
3 b 3 z y
【讨论】:
好吧,我的是最差的,你的是最好的:) @Stryder 我强烈反对:)
这非常适用于我在 col1 中寻找最小值索引的特殊情况。如果我有一个更一般的条件:“将与 'col1' 的 真实条件 对应的 'col2' 的值分配给 'col3',按 'col0' 分组”怎么办?
@makpalan 我不确定你所说的真实条件是什么意思,但也许它也可以放在上面的loc
中而不是idxmin
。您能否详细说明情况以及一些示例输入/输出(通过编辑问题)?如果这会使当前的问题变得非常不同,那么您可能会选择问另一个问题,但如果它足够接近,也许没问题,谢谢。
@MustafaAydın 说我想要 col3 的 col2 的(第一个)值,其中 col1>0(与最小值不同的条件,即使在这里微不足道),然后我发现了这个:df["col3"] = df.groupby("col0").col1.transform(lambda x: df.loc[x.index[x>0].tolist()[0], 'col2'])
。按照您的方法实际上可以得到更通用的东西,这实际上是我正在寻找的,谢谢【参考方案3】:
您可以使用 groupby.apply 获取一个系列,然后将其合并到 df 中
df
col0 col1 col2
0 a 0 w
1 a 1 x
2 b 2 y
3 b 3 z
col3 = df.groupby("col0").apply(lambda x: x.loc[x["col1"].idxmin(), "col2"])
col3.name = "col3"
df = df.merge(col3, how="left", left_on= "col0", right_index= True)
df
col0 col1 col2 col3
0 a 0 w w
1 a 1 x w
2 b 2 y y
3 b 3 z y
【讨论】:
以上是关于在带有 Groupby 的 Pandas 中:从以另一列为条件的列中分配一个值的主要内容,如果未能解决你的问题,请参考以下文章
带有最小值、最大值和总和的 Pandas 数据框 Groupby
Python Pandas - 带有 apply() 和 rolling() 的 groupby() 非常慢
带有 MultiIndexing 的 Pandas 数据框中的 Groupby