【问题标题】:How to delete the first and last rows with NaN of a dataframe and replace the remaining NaN with the average of the values below and above?如何使用数据帧的 NaN 删除第一行和最后一行,并将剩余的 NaN 替换为低于和高于值的平均值?
【发布时间】:2020-04-21 19:37:53
【问题描述】:

我们以这个数据框为例:

df = pd.DataFrame(dict(Col1=[np.nan,1,1,2,3,8,7], Col2=[1,1,np.nan,np.nan,3,np.nan,4], Col3=[1,1,np.nan,5,1,1,np.nan]))

   Col1  Col2  Col3
0   NaN   1.0   1.0
1   1.0   1.0   1.0
2   1.0   NaN   NaN
3   2.0   NaN   5.0
4   3.0   3.0   1.0
5   8.0   NaN   1.0
6   7.0   4.0   NaN

我想先删除第一行和最后一行,直到第一行和最后一行不再有 NaN。

中间预期输出:

   Col1  Col2  Col3
1   1.0   1.0   1.0
2   1.0   NaN   NaN
3   2.0   NaN   5.0
4   3.0   3.0   1.0

然后,我想用下面不是 NaN 的最接近的值的平均值替换剩余的 NaN,以及上面的那个。

最终预期输出:

   Col1  Col2  Col3
0   1.0   1.0   1.0
1   1.0   2.0   3.0
2   2.0   2.0   5.0
3   3.0   3.0   1.0

我知道我可以通过

在我的数据框中获得 NaN 的位置
df.isna()

但我无法解决我的问题。请问我该怎么办?

【问题讨论】:

    标签: python pandas dataframe nan


    【解决方案1】:

    我的做法:

    # identify the rows with some NaN
    s = df.notnull().all(1)
    
    # remove those with NaN at beginning and at the end:
    new_df = df.loc[s.idxmax():s[::-1].idxmax()]
    
    # average:
    new_df = (new_df.ffill()+ new_df.bfill())/2
    

    输出:

       Col1  Col2  Col3
    1   1.0   1.0   1.0
    2   1.0   2.0   3.0
    3   2.0   2.0   5.0
    4   3.0   3.0   1.0
    

    【讨论】:

      【解决方案2】:

      另一种选择是将DataFrame.interpolateround 一起使用:

      nans = df.notna().all(axis=1).cumsum().drop_duplicates()
      low, high = nans.idxmin(), nans.idxmax()
      
      df.loc[low+1: high].interpolate().round()
      
         Col1  Col2  Col3
      1   1.0   1.0   1.0
      2   1.0   2.0   3.0
      3   2.0   2.0   5.0
      4   3.0   3.0   1.0
      

      【讨论】:

      • 我认为这里的1.03.0 只是样本数据,所以interpolate().round() 通常不会给你平均值。
      猜你喜欢
      • 2021-11-04
      • 2021-12-05
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 2016-01-08
      • 2017-08-14
      • 2013-04-01
      相关资源
      最近更新 更多