使用以前有效值的趋势在数据框中填写NaN

2024-04-23 09:44:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过分组来填补数据中的空白,然后使用以前数据点的趋势来预测缺失的值

df

Group  Week  Value
B      1     5
B      2     6
B      3     NaN
B      4     NaN
B      5     NaN
B      6     8
B      7     8
B      8     7
B      9     6
B      10    NaN

从图形上看是这样的: Initial df plot

一旦实现了所需的功能,数据帧将如下所示:

Group  Week  Value
B      1     5
B      2     6
B      3     7
B      4     8
B      5     9
B      6     8
B      7     8
B      8     7
B      9     6
B      10    5.5

找到这些NaN值的前几点的趋势如图所示: NaN values calculated

本例中的前三个NaN值是通过简单地绘制值56,找到线性方程(y=mx+c)并将x拟合为计算y的周来找到的。将对所有NaN值执行相同的过程

我已经尝试过插值(df = df.groupby('Group').apply(lambda group: group.interpolate(method='index'))),但这显然是在寻找下一个有效的数据点,并将其包含在计算中,这是我试图避免的

可能值得注意的是,我使用的数据帧有200000行和4000组


Tags: 数据功能图形dfplotvaluegroupnan
1条回答
网友
1楼 · 发布于 2024-04-23 09:44:29

您可以创建子组序列g,并将method="spline"order=1传递给interpolate

g = df['Value'].mask(df['Value'].notnull(), df['Value'].isnull().cumsum()).ffill()
df['Value'] = (df.groupby(['Group', g])['Value']
                 .apply(lambda x: x.interpolate(method="spline", order=1)))
df
Out[1]: 
  Group  Week  Value
0     B     1    5.0
1     B     2    6.0
2     B     3    7.0
3     B     4    8.0
4     B     5    9.0
5     B     6    8.0
6     B     7    8.0
7     B     8    7.0
8     B     9    6.0
9     B    10    5.5

获取g的中间步骤如下所示

g = df['Value'].mask(df['Value'].notnull(), df['Value'].isnull().cumsum()).ffill()
g
Out[1]: 
0    0.0
1    0.0
2    0.0
3    0.0
4    0.0
5    3.0
6    3.0
7    3.0
8    3.0
9    3.0

这些数字基本上只是创建子组。我的方法是实现这一目标的一种方法


根据您的评论,我创建了一个maskm,用于计算大小为1的组。然后,我使用fillna()组合了不同的方法:

df = pd.DataFrame({'Group': {0: 'A',
  1: 'B',
  2: 'B',
  3: 'B',
  4: 'B',
  5: 'B',
  6: 'B',
  7: 'B',
  8: 'B',
  9: 'B'},
 'Week': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10},
 'Value': {0: 5.0,
  1: 6.0,
  2: np.nan,
  3: np.nan,
  4: np.nan,
  5: 8.0,
  6: 8.0,
  7: 7.0,
  8: 6.0,
  9: np.nan}})
g = df['Value'].iloc[1:].mask(df['Value'].notnull(), df['Value'].isnull().cumsum()).ffill()
m = df.groupby(['Group', g])['Value'].transform('count') > 1
v1 = (df[m].groupby(['Group', g])['Value']
                     .apply(lambda x: x.interpolate(method="spline", order=1)))
v2 = (df.groupby(['Group', g])['Value']
                     .apply(lambda x: x.interpolate(method="index")))
df['Value'] = df['Value'].fillna(v1).fillna(v2)
df

相关问题 更多 >