【问题标题】:lookup, interpolate and match between pandas dataframes在 pandas 数据帧之间查找、插值和匹配
【发布时间】:2018-05-08 14:49:22
【问题描述】:

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

我有两个 pandas 数据框 A 和 B,每个都包含 float64 值,它们都具有相同的尺寸和相同的索引和列 float64 数字条目。例如

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 返回的值将是在 B 中查找第 1.5 列的索引,因此返回介于 0.042486 和 0.100487 之间的某个值,接近但小于 0.100487 值。我想在 A 中返回这些“0.25”坐标值,并在 B 中的每一列中查找和插入等效值。

有点混乱,有意义吗?

我做了很多搜索,可以找到一些pandas dataframe插值方法,但一般都是在填充NaN的上下文中。

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

【问题讨论】:

  • Nick Holden 在这里解决了第二部分,非常好,tku。 [stackoverflow.com/questions/10464738/…第一部分是通过数据帧A(例如z = 0.25)为行z = some_value获取一组插值索引和列值
  • 我没有正确链接到 Nick Holden 的部分解决方案,[stackoverflow.com/a/30733959/8195971]
  • 我已经解决了这个问题,等我整理一下再发布我的解决方案。

标签: python pandas dataframe interpolation


【解决方案1】:

我相信这可以改进,不过,我还是会发布它......

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2019-03-16
    • 2020-10-14
    • 2021-08-21
    • 2020-05-24
    相关资源
    最近更新 更多