用前一行和下一行的平均值填充 NaN 值 - Python

Posted

技术标签:

【中文标题】用前一行和下一行的平均值填充 NaN 值 - Python【英文标题】:Fill NaN value with the mean of the previous and the next row - Python 【发布时间】:2021-10-01 16:36:53 【问题描述】:

我必须替换像这样组织的数据集的 NaN 值

细分:安达曼和尼科巴群岛 年份:1901 一月:49.20 二月:87.10 三月:南 四月:19.10 五月:89.99

(实际上一年中的所有月份都显示在列中)

我必须用前一年 (1900) 和下一年 (1902) 的平均值替换 NaN 值,如果可能的话,还可以添加同年下个月的值 (APR 1901 ) 取这三个值的平均值。

import pandas as pd
import numpy as np
import statistics
# Loop through rows of dataframe by index i.e. from 0 to number of rows
for i in range(0, df.shape[0]):
  for j in range(1, df.shape[1]):  #iterate over columns
   if pd.isna(df.iloc[i,j]):
     adjacentYearBefore = df.iloc[i-1,j].mean()
     adjacentYearAfter= df.iloc[i+1,j].mean()
     #avgYear = ((np.float64(adjacentYearBefore)) + (np.float64(adjacentYearAfter))) / 2.0
     avgYear = (adjacentYearBefore + adjacentYearAfter).mean()
     print(avgYear)
     df.iloc[i,j] = df.iloc[i,j].fillna(avgYear)

但是把这个还给我

AttributeError                            Traceback (most recent call last)
<ipython-input-29-32c064fa8ca4> in <module>()
     11      avgYear = (adjacentYearBefore + adjacentYearAfter).mean()
     12      print(avgYear)
---> 13      df.iloc[i,j] = df.iloc[i,j].fillna(avgYear)
     14      #df.iloc[i,j].ffill(inplace=True)
     15      #

AttributeError: 'numpy.float64' object has no attribute 'fillna'

当然,我已经阅读了关于堆栈溢出的类似问题,但我仍然无法解决我的问题。

更新

df.head(10)

output of df.head(10)

【问题讨论】:

拜托,您能否使用df.head(10) 的输出更新您的帖子以了解数据框。 查看pandas.Series.interpolate,它完全符合您的要求pandas.pydata.org/pandas-docs/stable/reference/api/…。 在我的情况下插值是线性的还是多项式的? 【参考方案1】:

我猜你到底在问什么:

我的数据框如下所示:

      annual
1901  3373.2
1902  3520.7
1903  2957.4
1904  3079.6
1905  2566.7
1906  2534.4
1907     NaN
1908  3576.4
1909  2899.4
1910  2687.2

nan如何填写前后一年的平均值?

回答:

df.interpolate()

给予

      annual
1901  3373.2
1902  3520.7
1903  2957.4
1904  3079.6
1905  2566.7
1906  2534.4
1907  3055.4
1908  3576.4
1909  2899.4
1910  2687.2

我猜对了您的问题吗?您对解决方案满意吗?注意顺便说一句。这使用默认的插值方法method=linear

进一步问题:我的代码有什么问题?

关于您的代码,几乎没有什么值得您注意的地方,也许您可​​以从中学习。 .mean in

     adjacentYearBefore = df.iloc[i-1,j].mean()
     adjacentYearAfter = df.iloc[i+1,j].mean()

不要做任何事情,因为你取的是一个值的平均值。

同样如此

     avgYear = (adjacentYearBefore + adjacentYearAfter).mean()

请注意,您首先将两个值相加,然后取该值的平均值,这样您就不会除以 2。

终于来了

     df.iloc[i,j] = df.iloc[i,j].fillna(avgYear)

您正在获取一个值并调用fillna。这是不可能的,因为应该在 seriesdataframe 填充所有值时调用 fillna。在这里你可以只分配值。

代码的工作版本:

for i in range(0, df.shape[0]):
      for j in range(1, df.shape[1]):  #iterate over columns
            if pd.isna(df.iloc[i,j]):
                adjacentYearBefore = df.iloc[i-1,j]
                adjacentYearAfter= df.iloc[i+1,j]
                avgYear = (adjacentYearBefore + adjacentYearAfter)/2
                print(avgYear)
                df.iloc[i,j] = avgYear

【讨论】:

感谢您的回答。请检查我发布的图像。我想用上一年和下一年的平均值替换一列的所有 NaN 值。所以不仅每年。可以使用我的解决方案中的给定算法来做到这一点吗?我运行了您的解决方案,但 NaN 值的数量始终相同。 默认情况下,所有列都会这样做。但它返回一个带有插入值的新数据框。我怀疑您检查了显然没有任何变化的旧数据框。所以我想你应该使用df = df.interpolate(). @Elisa 不客气。另请注意,我现在尝试从之前的评论中回答您的其他问题。

以上是关于用前一行和下一行的平均值填充 NaN 值 - Python的主要内容,如果未能解决你的问题,请参考以下文章

熊猫(Python):用前一行值填充空单元格?

SQL:如何根据条件用前一行值填充空单元格?

合并 Pandas 数据框中的 2 列,用前一个值填充 NaN [重复]

Python Pandas - 用前一列的值向前填充整行

如何用前一行的值填充空列?

06 pandas DataFrame - 数据过滤、NaN处理、统计方法