在 python pandas 中,如何对 DataFrame 进行重新采样和插值?

In python pandas, how can I re-sample and interpolate a DataFrame?

我有一个 pd DataFrame,通常采用这种格式:

   1       2          3          4  
0.1100 0.0000E+00 1.0000E+00 5.0000E+00  
0.1323 7.7444E-05 8.7935E-01 1.0452E+00  
0.1545 4.3548E-04 7.7209E-01 4.5432E-01  
0.1768 1.2130E-03 6.7193E-01 2.6896E-01  
0.1990 2.5349E-03 5.7904E-01 1.8439E-01  
0.2213 4.5260E-03 4.9407E-01 1.3771E-01 

我想做的是从列表中重新采样第 1 列(索引)值,例如:

indexList = numpy.linspace(0.11, 0.25, 8)

然后我需要从输入 DataFrame 对第 2、3 和 4 列的值进行线性插值(我 re-sample/reindex 始终只有我的第 1 列)- 如有必要,进行外推,因为 min/max 我列表的值不一定在我现有的第 1 列(索引)内。然而关键是插值部分。我对 python 很陌生,但我在考虑使用这样的方法:

  1. output_df = DataFrame.reindex(index=indexList) - 这将主要为第 2-4 列提供 NaN。
  2. 为索引,行在output_df.iterrows()
    “计算 interpolated/extrapolated 值的函数 DataFrame 并将它们插入正确的 row/column"

不知何故感觉我应该能够使用 .interpolate 功能,但我不知道如何使用。我不能直接使用它——它太不准确了,因为在第 2-4 列中提到的重新索引后我的大部分条目都是 NaN;插值应该在我的初始 DataFrame 的两个最接近的值内完成。有什么好的建议吗? (如果我的 format/intension 不清楚,请告诉我...)

假设第 1 列在索引中,您可以使用原始值和您创建的列表重新索引数据框,然后使用插值来填充 nan。

df1 = df.reindex(df.index.union(np.linspace(.11,.25,8)))
df1.interpolate('index')

               2         3         4
0.1100  0.000000  1.000000  5.000000
0.1300  0.000069  0.891794  1.453094
0.1323  0.000077  0.879350  1.045200
0.1500  0.000363  0.793832  0.574093
0.1545  0.000435  0.772090  0.454320
0.1700  0.000976  0.702472  0.325482
0.1768  0.001213  0.671930  0.268960
0.1900  0.001999  0.616698  0.218675
0.1990  0.002535  0.579040  0.184390
0.2100  0.003517  0.537127  0.161364
0.2213  0.004526  0.494070  0.137710
0.2300  0.004526  0.494070  0.137710
0.2500  0.004526  0.494070  0.137710

在我们开始一些咒语之前:

import pandas as pd
import numpy

LENGTH=8

让我们从加载您的数据开始(我们将更改为 csv,因为它更容易):

x="""   1       2          3          4
0.1100 0.0000E+00 1.0000E+00 5.0000E+00
0.1323 7.7444E-05 8.7935E-01 1.0452E+00
0.1545 4.3548E-04 7.7209E-01 4.5432E-01
0.1768 1.2130E-03 6.7193E-01 2.6896E-01
0.1990 2.5349E-03 5.7904E-01 1.8439E-01
0.2213 4.5260E-03 4.9407E-01 1.3771E-01
"""
nx = ""
for l in x.split('\n'):
    nx += ','.join(l.split()) + '\n'
df= pd.read_csv(pd.compat.StringIO(nx))

现在,您想要一个新的数据帧插值到相同的数据上,但包含 0.11 到 0.25 之间的 8 个值的数组:

indexList = numpy.linspace(0.11, 0.25, LENGTH)

我们将使用第一列作为索引,并重新索引:

df_interpolated = df.reindex(df.index.union(indexList)).interpolate('index')
df_interpolated.head(LENGTH)

             1         2         3         4
0.00  0.110000  0.000000  1.000000  5.000000
0.11  0.112453  0.000009  0.986729  4.564972
0.13  0.112899  0.000010  0.984316  4.485876
0.15  0.113345  0.000012  0.981903  4.406780
0.17  0.113791  0.000013  0.979490  4.327684
0.19  0.114237  0.000015  0.977077  4.248588
0.21  0.114683  0.000016  0.974664  4.169492
0.23  0.115129  0.000018  0.972251  4.090396
0.25  0.115575  0.000019  0.969838  4.011300