我有一些数据帧,看起来像下面的例子:
- 每一行是一个观测期,每一列是我正在测量的数量(例如,纽约的降雨量)
- 一些列以nan开头和结尾
- 大多数列在第一个和最后一个填充值之间有nan
期望输出值:对于每一列,将第一个和最后一个值之间的nan转换为0,不修改开头和结尾的nan
:将[nan,7,6,nan,9,nan]
转换为[nan,7,6,0,9,nan]
我试过了:
查找Pandas DataFrame中的第一个和最后一个非NaN值很容易找到每个列的第一个和最后一个非空值因此,我可以遍历每个列,然后在每个列的第一个和最后一个非空值之间循环,并将nan替换为零。它可以工作,但它当然不是矢量化的,缓慢且低效。你能想到一个更好的选择吗?
对于每一列,我可以查询数据框以找到第一列和最后一列之间的nan,但是我仍然需要循环遍历所有列。
import numpy as np
np.random.seed(5)
import pandas as pd
rows = 20
df =pd.DataFrame(index = np.arange(0,rows), columns =['New York', 'London','Paris'], data = np.random.rand(rows,3))
df.iloc[0:2,0] = np.nan
df.iloc[0:3,1] = np.nan
df.iloc[-3:,0] = np.nan
df.iloc[-2:,1] = np.nan
df.iloc[7,0] = np.nan
df.iloc[10,0] = np.nan
df.iloc[9,1] = np.nan
df.iloc[11,2] = np.nan
first_notna = df.apply(pd.Series.first_valid_index)
last_notna = df.apply(pd.Series.last_valid_index)
out = df.copy()
for numcol, col in enumerate(df.columns):
for r in np.arange( first_notna.loc[col], last_notna.loc[col] + 1 ):
if np.isnan( df.iloc[r,numcol]):
out.iloc[r,numcol] = 0
从另一个堆栈溢出答案复制解决方案:填充pandas dataframe中缺少的中间值
使用bfill和fill的组合首先获得一个布尔值df,表示该行不是尾随nan还是前导nan。然后用0
填充df[df.bfill().notnull() & df.ffill().notnull()] = df.fillna(0)