Python中的线性插值,但使用列标题作为索引值

时间:2017-08-13 13:33:37

标签: python pandas dataframe linear-interpolation

我有一个缺少值的数据框,我需要在列间水平插值。对于插值,某些列的名称(名称为数字)将用作插值的索引值。我将以下示例放在一起以更好地传达问题:

初始数据框:

import pandas as pd
testdata1 = [('Prod', ['P1', 'P2']),
 ('A', ['1', '1']),
 ('1', ['10', '40']),
 ('2', ['', '']),
 ('3', ['30', '80']),
 ('B', ['1', '2']),             
 ]
df = pd.DataFrame.from_items(testdata1)
df

Initial df

目标数据框:

targetdf = [('Prod', ['P1', 'P2']),
 ('A', ['1', '1']),
 ('1', ['10', '40']),
 ('2', ['20', '60']),
 ('3', ['30', '80']),
 ('B', ['1', '2']),             
 ]
df2 = pd.DataFrame.from_items(targetdf)
df2

Target df

在上面的示例中,执行插值(水平)的列是列' 1'' 2'和'。那些列标题(1,2和3)是插值计算中使用的索引值。

我知道如何在Python中使用.interpolate(),但仅当索引值是一个特定列中的所有单元格时。非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您可以将apply与参数axis=1一起用于按行处理:

#replace whitespaces to NaNs
df = df.replace('', np.nan)
#rename columns from strings to number
d = {'1':1,'2':2,'3':3}
df = df.rename(columns=d)
#columns for interploate (necessary numeric)
cols = [1,2,3]

#convert values in cols to floats first, interpolate and if int output convert to int last
df[cols] = df[cols].astype(float)
                   .apply(lambda x: x.interpolate(method='index'), axis=1)
                   .astype(int)
print (df)
  Prod  A   1   2   3  B
0   P1  1  10  20  30  1
1   P2  1  40  60  80  2

答案 1 :(得分:0)

您提到列名称是数字,但它们在您提供的示例数据中列为字符串。如果它们实际上是数字类型,interpolate()应该可以正常工作:

import numpy as np
import pandas as pd

testdata1 = [('Prod', ['P1', 'P2']),
             ('A', [1., 1.]),
             (1, [10., 40.]),
             (2, [np.nan, np.nan]),
             (3, [30., 80.]),
             ('B', [1., 2.]),             
            ]
df = pd.DataFrame.from_items(testdata1)

cols = [1,2,3]
df[cols] = df[cols].interpolate(method="index", axis=1)

输出:

  Prod    A     1     2     3    B
0   P1  1.0  10.0  20.0  30.0  1.0
1   P2  1.0  40.0  60.0  80.0  2.0

答案 2 :(得分:0)

转换为数字并应用interpolate

In [104]: cols = ['1','2','3']

In [105]: df[cols].apply(pd.to_numeric).interpolate(axis=1)
Out[105]:
      1     2     3
0  10.0  20.0  30.0
1  40.0  60.0  80.0