如何在pandas中插入和填充计算值的行?



我有一个缺少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

我该怎么做?

您可以使用interpolateffill:

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.reindexbyrange,将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

相关内容

  • 没有找到相关文章