用前一行和下一行的平均值填充 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
。这是不可能的,因为应该在 series
或 dataframe
填充所有值时调用 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的主要内容,如果未能解决你的问题,请参考以下文章