在 pandas 列中查找下一个非空行
Find next non-blank row in pandas column
给定 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
我想return一个非空a
之后的下一个非空b
的位置和值,把这个位置 和 value 到非空白 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
结果应该是 a
的 Date_Time 索引。
不会有 a
和 b
在同一条线上 - 它们是随时间变化的(坦克水平)的最小值和最大值。
想法是在 b 列和索引上使用 bfill
来获取位置:
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())
给定 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
我想return一个非空a
之后的下一个非空b
的位置和值,把这个位置 和 value 到非空白 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
结果应该是 a
的 Date_Time 索引。
不会有 a
和 b
在同一条线上 - 它们是随时间变化的(坦克水平)的最小值和最大值。
想法是在 b 列和索引上使用 bfill
来获取位置:
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())