我有两个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的背景下。
我非常感谢您的帮助,所以,请提前感谢您阅读和思考这一点。也许这是一个简单的解决方案,但我无法想到它或在任何地方在线找到它。
答案 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