我相信有更好的方式来描述我正在做的事情,但这里有一个例子。假设我有一个数据帧:
d = {'col1': [1, 5, 10, 22, 36, 57], 'col2': [100, 450, 1200, 2050, 3300, 6000]}
df = pd.DataFrame(data=d)
df
col1 col2
0 1 100
1 5 450
2 10 1200
3 22 2050
和第二个数据帧(或者序列):
d2 = {'col2': [100, 200, 450, 560, 900, 1200, 1450, 1800, 2050, 2600, 3300, 5000, 6000]}
df2 = pd.DataFrame(data=d2)
df2
col2
0 100
1 200
2 450
3 560
4 900
5 1200
6 1450
7 1800
8 2050
9 2600
10 3300
11 5000
12 6000
我需要一些有效的方法来为df2中的第二列赋值,如下所示:
- 如果df2['col2']中的值与df['col2']中的值匹配,则在同一行中分配df['col1']的值。
- 如果没有匹配的值,找到它适合的范围并在此基础上近似该值。例如,对于df2。loc[1,'col2'], col2的值是200,它在第一个数据帧中属于100到450之间,所以新值将是(5-1)/(450-100)*200 = 2.2857
编辑:正确的例子应该是(5 - 1)/(450 - 100)* (200 - 100)+1 = 2.1429
既然你确认了你的要求,我们可以做一个解决方案。我们可以使用循环来查找由非nan值包围的片段,并对中间的点进行线性插值。
此算法仅在col1
被两端的非nan值锚定时有效,因此assert
语句。
col1, col2 = df2.merge(df, how='left', on='col2')[['col1', 'col2']].to_numpy().T
assert ~np.isnan(col1[[0, -1]]).any(), 'First and last elements of col1 must not be NaN'
n = len(col1)
i = 0
while i < n:
j = i + 1
while j < n and np.isnan(col1[j]):
j += 1
if j - i > 1:
# The linear equation
f = np.polyfit(col2[[i,j]], col1[[i,j]], deg=1)
# Apply the equation on all points between i and j
col1[i:j+1] = np.polyval(f, col2[i:j+1])
i = j
您是否考虑过在第一个数据框架上训练回归模型,然后预测第二个数据框架的值?
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html