我有许多数据框,如下例所示:
- 每一行是一个观察期,每列是我正在测量的一个量(例如纽约的降雨量)
- 一些列以一些 nan 开始和结束
- 大多数列在第一个和最后一个填充值之间都有 nan
期望输出:对于每一列,将第一个值和最后一个值之间的nans转换为0,而不修改开头和结尾的nans
示例:将 [nan,7,6,nan,9,nan]
转换为 [nan,7,6,0,9,nan]
我尝试过的:
基于Locate first and last non NaN values in a Pandas DataFrame很容易找到每列的第一个和最后一个非空值 因此,我可以循环遍历每一列,然后对于每一列在第一个和最后一个非空值之间循环,并将 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
最佳答案
从另一个堆栈溢出答案复制解决方案:Filling missing middle values in pandas dataframe
使用 bfill 和 ffill 的组合首先获取 bool 值 df,判断该行是否不是尾随或前导 nan。然后用 0 填充这些
df[df.bfill().notnull() & df.ffill().notnull()] = df.fillna(0)
关于python - 仅转换每列的第一个和最后一个填充值之间的 nan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66030356/