1

给定一个 Pandas 数据框

df = pd.DataFrame({'a': [None,1,None,None,2,None], 'b': [None,None,None,3,None,4]})

     a    b
0  NaN  NaN
1  1.0  NaN
2  NaN  NaN
3  NaN  3.0
4  2.0  NaN
5  NaN  4.0

我想在 non-blankb之后返回下一个 non-blank 的位置和值a,并将这个位置放入 non-blank 旁边的新列中a,所以:

     a    b position  value
0  NaN  NaN      NaN    NaN
1  1.0  NaN        3    3.0
2  NaN  NaN      NaN    NaN
3  NaN  3.0      NaN    NaN
4  2.0  NaN        5    4.0
5  NaN  4.0      NaN    NaN

如果有任何区别,则索引是一个Date_Time值,position结果应该是 的 Date_Time 索引a

不会有ab在同一条线上 - 它们是随着时间的推移(坦克水平)的最小值和最大值。

4

1 回答 1

3

这个想法是bfill在 b 列上使用 , 并且在索引上使用来获取位置:

df = pd.DataFrame({'a': [None,1,None,None,2,None], 'b': [None,None,None,3,None,4]})
df = df.reset_index().rename(columns = {'index':'position'})
df.loc[df['b'].isna(),'position'] = None
df.loc[df['a'].notna(),'position'] = df['position'].bfill()
df.loc[df['a'].isna(),'position'] = None
df.loc[df['a'].notna(),'value'] = df['b'].bfill()
df[['a','b', 'position', 'value']]

输出

      a    b    position    value
--  ---  ---  ----------  -------
 0  nan  nan         nan      nan
 1    1  nan           3        3
 2  nan  nan         nan      nan
 3  nan    3         nan      nan
 4    2  nan           5        4
 5  nan    4         nan      nan

另一种解决方案

更优雅,但可读性可能略低。相同的想法,bfill但现在使用where

df = pd.DataFrame({'a': [None,1,None,None,2,None], 'b': [None,None,None,3,None,4]})
df['position'] = df.index.where(df['b'].notna())
df['position'] = df['position'].bfill().where(df['a'].notna())
df['value'] = df['b'].bfill().where(df['a'].notna())
于 2022-01-27T23:13:17.193 回答