我有一个缺少theta步的pandas数据框架,如下所示,
index name theta r
1 wind 0 10
2 wind 30 17
3 wind 60 19
4 wind 90 14
5 wind 120 17
6 wind 210 18
7 wind 240 17
8 wind 270 11
9 wind 300 13
我需要加上缺失的值,
index name theta r
1 wind 0 10
2 wind 30 17
3 wind 60 19
4 wind 90 14
5 wind 120 17
6 wind 150 null
7 wind 180 null
8 wind 210 18
9 wind 240 17
10 wind 270 11
11 wind 300 13
12 wind 330 null
然后用线性插值填充空值。为简单起见,这里我们可以考虑前一个和下一个可用值的平均值,
index name theta r
1 wind 0 10
2 wind 30 17
3 wind 60 19
4 wind 90 14
5 wind 120 17
6 wind 150 17.5 #(17 + 18)/2
7 wind 180 17.5 #(17 + 18)/2
8 wind 210 18
9 wind 240 17
10 wind 270 11
11 wind 300 13
12 wind 330 11.5 #(13 + 10)/2
我该怎么做?
您可以使用interpolate
和ffill
:
out = (
df.set_index('theta').reindex(range(0, 330+1, 30))
.interpolate().ffill().reset_index()[df.columns]
)
输出:
name theta r
0 wind 0 10.000000
1 wind 30 17.000000
2 wind 60 19.000000
3 wind 90 14.000000
4 wind 120 17.000000
5 wind 150 17.333333
6 wind 180 17.666667
7 wind 210 18.000000
8 wind 240 17.000000
9 wind 270 11.000000
10 wind 300 13.000000
11 wind 330 13.000000
执行循环插值,您只能用limit_area='inside'
填充内部值,然后用fillna
填充第一行和最后一行的平均值:
out = (
df.set_index('theta').reindex(range(0, 330+1, 30))
.interpolate(method='linear', limit_area='inside')
.pipe(lambda d: d.fillna(d.dropna().iloc[[0, -1]].select_dtypes('number').mean()))
.ffill().reset_index()[df.columns]
)
输出:
name theta r
0 wind 0 10.000000
1 wind 30 17.000000
2 wind 60 19.000000
3 wind 90 14.000000
4 wind 120 17.000000
5 wind 150 17.333333
6 wind 180 17.666667
7 wind 210 18.000000
8 wind 240 17.000000
9 wind 270 11.000000
10 wind 300 13.000000
11 wind 330 11.500000
如果你真的想要多个中间值相同的值,另一个选择可能是自己计算平均值(使用ffill
/bfill
):
tmp = df.set_index('theta').reindex(range(0, 330+1, 30))
tmp2 = tmp.ffill()
out = ((tmp2+tmp.bfill().fillna(df.iloc[0]))
.select_dtypes('number').div(2)
.combine_first(tmp2).reset_index()[df.columns]
)
输出:
name theta r
0 wind 0 10.0
1 wind 30 17.0
2 wind 60 19.0
3 wind 90 14.0
4 wind 120 17.0
5 wind 150 17.5 # same values
6 wind 180 17.5 #
7 wind 210 18.0
8 wind 240 17.0
9 wind 270 11.0
10 wind 300 13.0
11 wind 330 11.5
NB。这些方法应该适用于任何数量的数字列(不仅仅是'r'
)。
处理组
一个简单的方法是使用函数和groupby.apply
:
def interp(df):
return (
df.set_index('theta').reindex(range(0, 330+1, 30))
.interpolate(method='linear', limit_area='inside')
.pipe(lambda d: d.fillna(d.dropna().iloc[[0, -1]].select_dtypes('number').mean()))
.ffill().reset_index()[df.columns]
)
out = df.groupby('name', group_keys=False).apply(interp)
或者,先pivot
你的数据:
out = (
df.pivot(index='theta', columns='name')
.reindex(range(0, 330+1, 30))
.interpolate(method='linear', limit_area='inside')
.pipe(lambda d: d.fillna(d.dropna().iloc[[0, -1]].select_dtypes('number').mean()))
.ffill().stack().reset_index()[df.columns]
)
输出示例(#
显示最初缺失的值):
name theta r
0 turb 0 100.000000
1 turb 30 170.000000
2 turb 60 190.000000
3 turb 90 140.000000
4 turb 120 170.000000
5 turb 150 173.333333 #
6 turb 180 176.666667 #
7 turb 210 180.000000
8 turb 240 170.000000
9 turb 270 110.000000
10 turb 300 130.000000
11 turb 330 115.000000 #
0 wind 0 10.000000
1 wind 30 17.000000
2 wind 60 19.000000
3 wind 90 14.000000
4 wind 120 17.000000 #
5 wind 150 17.333333 #
6 wind 180 17.666667
7 wind 210 18.000000
8 wind 240 17.000000
9 wind 270 11.000000
10 wind 300 13.000000
11 wind 330 11.500000 #
Withbfill
/ffill
:
tmp = (df.set_index(['name', 'theta'])
.reindex(pd.MultiIndex.from_product([df['name'].unique(), range(0, 330+1, 30)],
names=['name', 'theta']
))
)
tmp2 = tmp.groupby(level='name').ffill()
out = ((tmp2+tmp.groupby(level='name').bfill().fillna(df.iloc[0]))
.select_dtypes('number').div(2)
.combine_first(tmp2).reset_index()[df.columns]
)
如果name
列中有相同的值,您可以使用DataFrame.reindex
byrange
,将s2
中的最后缺失值替换为s1
的第一个值:
df1 = df.set_index('theta').reindex(range(0, 360, 30))
s1 = df1['r'].ffill()
s2 = df1['r'].bfill().fillna(s1.iat[0])
df = s1.add(s2).div(2).reset_index().assign(name = 'wind')[df.columns]
print (df)
name theta r
0 wind 0 10.0
1 wind 30 17.0
2 wind 60 19.0
3 wind 90 14.0
4 wind 120 17.0
5 wind 150 17.5
6 wind 180 17.5
7 wind 210 18.0
8 wind 240 17.0
9 wind 270 11.0
10 wind 300 13.0
11 wind 330 11.5
用DataFrame.interpolate
和辅助行通过r
的回填值插值的解:
df1 = df.set_index('theta').reindex(range(0, 360, 30))
df = (pd.concat([df1, df1[['r']].bfill().iloc[[0]]])
.interpolate().reset_index().iloc[:-1].assign(name='wind')[df.columns])
print (df)
name theta r
0 wind 0 10.000000
1 wind 30 17.000000
2 wind 60 19.000000
3 wind 90 14.000000
4 wind 120 17.000000
5 wind 150 17.333333
6 wind 180 17.666667
7 wind 210 18.000000
8 wind 240 17.000000
9 wind 270 11.000000
10 wind 300 13.000000
11 wind 330 11.500000
如果可能的话,缺少第一行:
print (df)
name theta r
2 wind 30 17
3 wind 60 19
4 wind 90 14
5 wind 120 17
6 wind 210 18
7 wind 240 17
8 wind 270 11
9 wind 300 13
df1 = df.set_index('theta').reindex(range(0, 360, 30))
df = (pd.concat([df1[['r']].ffill().iloc[[-1]],
df1,
df1[['r']].bfill().iloc[[0]]])
.interpolate().reset_index().iloc[1:-1].assign(name='wind')[df.columns])
print (df)
name theta r
1 wind 0 15.000000
2 wind 30 17.000000
3 wind 60 19.000000
4 wind 90 14.000000
5 wind 120 17.000000
6 wind 150 17.333333
7 wind 180 17.666667
8 wind 210 18.000000
9 wind 240 17.000000
10 wind 270 11.000000
11 wind 300 13.000000
12 wind 330 15.000000