根据组和另一个字符串列的最大值填充NaN,并使用NaN行中的值



我有一个如下所示的输入数据:

df = pd.DataFrame({"colony" : [22, 22, 22, 33, 33, 33],
"measure" : [np.nan, 7, 11, 13, np.nan, 9,],
"net/gross" : [np.nan, "gross", "net", "gross", "np.nan", "net"]})
df
colony  measure  net/gross
0   22      NaN      NaN  
1   22      7        gross
2   22      11       net
3   33      13       gross
4   33      NaN      NaN
5   33      9        net

我想用每个群体的最大值填充measure列的NaN,然后将net/gross列中的NaN填写为度量值最大的行处的net/gross值(例如,将索引0处的NaN填写为度量值最大处对应的值,即"net"),并创建一个注释列以";max_fillled"记录所有NaN填充的行。其他行为"未改变"得到如下输出:

colony  measure  net/gross   remarks
0   22      11      net         max_filled
1   22      7       gross       unchanged
2   22      11      net         unchanged
3   33      13      gross       unchanged
4   33      13      gross       max_filled
5   33      9       net         unchanged

我的解决方案

我要做的是计算max 的一列
mx=df.groupby('colony').measure.transform(max)

和要填充的行列表

f=df.measure.isna()

然后用它们来填充你想要的

df['remarks']='unchanged'
df.loc[f, 'measure']=mx
df.loc[f, 'net/gross']=df[f]['net/gross']
df.loc[f, 'remarks']='max_filled'

评论类似问题的其他答案

请注意,这个更简单的问题的答案,它只是用每组的平均值填充NaN,你可以很容易地适应用max代替mean,但这无助于填充其他2列,似乎一致促进基于lambda的解决方案。

这通常是个坏主意。我是说,我喜欢,我是从微积分学来的。但是在pandas中,apply或类似的方法只是行上的旧的for循环之后最糟糕的事情(甚至有时,for循环更快)。

答案的一致使我产生了怀疑。但是,好吧,是时候结束辩论了:即使对于那个更简单的问题,我的解决方案也比这个问题的答案快。

也就是说,用这种方法填充NaN会更快

mx=df.groupby('colony').measure.transform(max)
f=df.measure.isna()
df.loc[f,'measure']=mx

而不是建议的方式

df["measure"] = df.groupby("colony")["measure"].transform(lambda x: x.fillna(x.mean()))

所以,我一开始试图看看之前的答案如何适应你更复杂的情况(其中转换的测量行也应该影响net/grossremarks)。但是没有理由这样做,因为它更快(快2.5倍),计算一个列max,然后做简单的列变换。

士气是

如果可以避免在数据框架上使用lambda(以及for和apply),则永远不要使用它。

即使以计算整个列的最大值为代价,其中只有一小部分将被真正使用,也最好坚持使用整个列代数。

这是使用.transform('max').transform('idxmax')的另一种方法

g = df.groupby('colony')['measure']
measure_max, ng_max = g.transform('max'),df.loc[g.transform('idxmax'),'net/gross'].reset_index(drop=True)
(df.fillna({'measure':measure_max,'net/gross':ng_max})
.assign(remarks = np.where(df['net/gross'].isna(),'max_filled','unchanged')))

输出:

colony  measure net/gross     remarks
0      22     11.0       net  max_filled
1      22      7.0     gross   unchanged
2      22     11.0       net   unchanged
3      33     13.0     gross   unchanged
4      33     13.0     gross  max_filled
5      33      9.0       net   unchanged

相关内容

  • 没有找到相关文章

最新更新