在pandas数据帧之间查找,插值和匹配

时间:2017-11-24 14:59:00

标签: python pandas dataframe interpolation

这是新的,这是我的第一个问题,我希望将来可以通过回答其他人的问题来回报。

我有两个pandas数据帧,A& B,每个都包含float64值,两者具有相同的尺寸和相同的索引和列float64数字条目。 E.g。

A
                        0.5       1.0       1.5       2.0
    -1.947417e-15  0.015178  0.045640  0.074928  0.100943
    -5.000000e-01  0.047697  0.149200  0.256133  0.359234
    -1.000000e+00  0.082972  0.272634  0.494826  0.733841
    -1.500000e+00  0.120121  0.417265  0.811659  1.303373
    -2.000000e+00  0.155978  0.572880  1.206698  2.159998


B
                        0.5       1.0       1.5       2.0
    -1.947417e-15  0.003859  0.018968  0.042486  0.070368
    -5.000000e-01  0.003859  0.036093  0.100487  0.187447
    -1.000000e+00 -0.007340  0.018968  0.107873  0.254083
    -1.500000e+00 -0.029713 -0.038906  0.042486  0.178620
    -2.000000e+00 -0.059926 -0.134084 -0.091504  0.032577

我希望能够在A中的每个数据列中查找固定值(例如0.25),返回每列的(线性)插值索引值(但仅当列值存在于列数据的范围内时)值 - 因此不是A)中的第0.5列。数据帧A将始终使列数据单调递增。

一旦我为数据帧A中的每一列插入了一个数据值的插值索引值,比如说0.25,那么我想检索数据框B中具有相同坐标的值,即插值索引和等效列值。

因此,例如,在A中查找0.25,然后在列1.5中查找将在0和-0.5之间插入索引,某处接近但大于值-0.5。从B返回的值将是对列1.5中的索引进行查找,因此返回介于0.042486和0.100487之间,接近但小于0.100487的值。我想要归还这些' 0.25' A中的坐标值和查找&插值为B中每列中的等价值。

有点混乱,有意义吗?

我已经做了很多搜索,可以找到一些pandas数据帧插值方法,但通常它们都是在填充NaN的背景下。

我非常感谢您的帮助,所以,请提前感谢您阅读和思考这一点。也许这是一个简单的解决方案,但我无法想到它或在任何地方在线找到它。

1 个答案:

答案 0 :(得分:0)

我确信这可以改进,但不管怎样,我会发布它...

import pandas as pd
from   numpy import nan
import numpy as np

A = np.array([0.015178, 0.045640, 0.074928, 0.100943,\
              0.047697, 0.149200, 0.256133, 0.359234,\
              0.082972, 0.272634, 0.494826, 0.733841,\
              0.120121, 0.417265, 0.811659, 1.303373,\
              0.155978, 0.572880, 1.206698, 2.159998]).reshape(5,4)

B = np.array([0.003859, 0.018968, 0.042486, 0.070368,\
              0.003859, 0.036093, 0.100487, 0.187447,\
             -0.007340, 0.018968, 0.107873, 0.254083,\
             -0.029713,-0.038906, 0.042486, 0.178620,\
             -0.059926,-0.134084,-0.091504, 0.032577]).reshape(5,4)

A = pd.DataFrame(A,index=np.arange(0,-2.1,-0.5),columns=np.arange(0.5,2.1,0.5))

B = pd.DataFrame(B,index=np.arange(0,-2.1,-0.5),columns=np.arange(0.5,2.1,0.5))


def get_level_intersection(grid, level, axis=0): 

    if (axis==0): 
        gd = grid.copy(deep=True)
    else:
        gd = grid.T.copy(deep=True)

    intersection = [] 
    columns=['a_value','b_value']
    if (axis==1): 
        columns=columns[::-1]

    for i in np.arange(len(gd.axes[1])):
        b_ind = gd.axes[1][i] 
        a_ind1 = gd[gd[:]>level].get(gd.axes[1][i]).first_valid_index()

        if (a_ind1 is not None): 
            a_loc = gd.axes[0].get_loc(a_ind1) 
            val_a1 = gd.get_value(a_ind1,gd.axes[1][i]) 

            if (a_loc != 0): 
                val_a = gd.get_value(gd.axes[0][a_loc-1],gd.axes[1][i])
                val_a_int = gd.axes[0][a_loc-1] + (gd.axes[0][1]-gd.axes[0][0]) * (level-val_a)/(val_a1-val_a)
            else:
                val_a = gd.get_value(gd.axes[0][0],gd.axes[1][i])
                val_a_int = (gd.axes[0][1]-gd.axes[0][0]) * (level-val_a)/(val_a1-val_a)

            intersection.append([val_a_int,gd.axes[1][i]])

    return pd.DataFrame(intersection, columns=columns)


def grid_interpolate(grid, x, y):
    gd = grid.copy(deep=True)
    if x not in gd.index:
        gd.ix[x] = nan
        gd = gd.sort()
        gd = gd.interpolate(method='index', axis=0).ffill(axis=0).bfill(axis=0)

    if y not in gd.columns.values:
        gd = gd.reindex(columns=np.append(gd.columns.values, y))
        gd = gd.sort_index(axis=1)
        gd = gd.interpolate(method='index', axis=1).ffill(axis=1).bfill(axis=1)

    return gd[y][x]


def curve_slice(grid1, grid2, level):

    gd1 = grid1.copy(deep=True)
    gd2 = grid2.copy(deep=True)

    intersection = []

    inter_cols = get_level_intersection(gd1, level)
    inter_rows = get_level_intersection(gd1, level, axis=1)
    intersection = pd.concat([inter_cols,inter_rows]).sort(inter_cols.columns[0]).reset_index(drop=True)
    intersection = intersection.append(pd.DataFrame(columns=['val']))

    for index, row in intersection.iterrows():
        intersection['val'][index]=grid_interpolate(gd2,row[0],row[1])

    return pd.DataFrame(intersection)


print(curve_slice(A,B,0.25))
>>
    a_value   b_value         val
0 -2.000000  0.612763 -0.07665051
1 -1.500000  0.718546 -0.03373118
2 -1.000000  0.940331  0.01582844
3 -0.908315  1.000000   0.0221082
4 -0.500000  1.471323  0.09679377
5 -0.483077  1.500000  0.09852392
6 -0.288545  2.000000   0.1379331

作为支票,

print(curve_slice(A,A,0.25))
>>
    a_value   b_value   val
0 -2.000000  0.612763  0.25
1 -1.500000  0.718546  0.25 
2 -1.000000  0.940331  0.25
3 -0.908315  1.000000  0.25
4 -0.500000  1.471323  0.25
5 -0.483077  1.500000  0.25
6 -0.288545  2.000000  0.25

print(get_level_intersection(A,0.25))
>>
    a_value  b_value
0 -0.908315      1.0
1 -0.483077      1.5
2 -0.288545      2.0

print(get_level_intersection(A,0.25,axis=1))
>>
    b_value  a_value
0  1.471323     -0.5
1  0.940331     -1.0
2  0.718546     -1.5
3  0.612763     -2.0