匹配两个不同长度的数据帧中的最近值
Matching nearest values in two dataframes of different lengths
如果我有两个不同长度、不同标签和不同数字精度级别的数据帧,如下所示:
df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})
如何找到两个数据帧在 'a' 和 'A' 列之间具有近似匹配值的行(比如在 2 位精度内),从而产生这样的数据帧
a b A B
------------------------------------------------
| 1.2345 | 4.123 | 1.2346 | 4.1232 |
| 2.2345 | 5.123 | 2.2343 | 5.1239 |
尝试次数:
尝试 #1:
matches_df = pd.merge(df1, df2, how='inner', left_on=['a'], right_on = ['A'])
这仅在 'a' 和 'A' 列之间存在完全匹配的情况下有效,但我不确定如何合并一个软糖因子以允许匹配精度在 2 位数字以内的行。
尝试 #2
matches_df = df1.loc[np.round(df1['a'],2)==np.round(df2['A'],2)]
这给出了错误“ValueError:只能比较相同标记的系列对象”,因为我认为两个数据帧有不同的标签('a','b' 和 'A','B').
关于如何实现这一点有什么想法吗?
使用KDTree,你可以在m O(log n)
中找到最接近df1
的数学,其中n
是df2
和m
df1
.
中的元素数
import pandas as pd
import numpy as np
from scipy.spatial import cKDTree
df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})
def spatial_merge_NN(df1, df2, xyz=['A', 'B']):
''' Add features from df2 to df1, taking closest point '''
tree = cKDTree(df2[xyz].values)
dists, indices = tree.query(df1[['a','b']].values, k=1)
fts = [c for c in df2.columns]
for c in fts:
df1[c] = df2[c].values[indices]
return df1
df_new = spatial_merge_NN(df1, df2, ['A', 'B'])
# a b A B
# 0 1.2345 4.123 1.2346 4.1232
# 1 2.2345 5.123 2.2343 5.1239
# 2 3.2345 6.123 2.2343 5.1239
它放置一个数据帧常量(在本例中为 df1
)并遍历 df2
并从 d2
中找到最接近的对并添加该行。
如果我有两个不同长度、不同标签和不同数字精度级别的数据帧,如下所示:
df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})
如何找到两个数据帧在 'a' 和 'A' 列之间具有近似匹配值的行(比如在 2 位精度内),从而产生这样的数据帧
a b A B
------------------------------------------------
| 1.2345 | 4.123 | 1.2346 | 4.1232 |
| 2.2345 | 5.123 | 2.2343 | 5.1239 |
尝试次数:
尝试 #1:
matches_df = pd.merge(df1, df2, how='inner', left_on=['a'], right_on = ['A'])
这仅在 'a' 和 'A' 列之间存在完全匹配的情况下有效,但我不确定如何合并一个软糖因子以允许匹配精度在 2 位数字以内的行。
尝试 #2
matches_df = df1.loc[np.round(df1['a'],2)==np.round(df2['A'],2)]
这给出了错误“ValueError:只能比较相同标记的系列对象”,因为我认为两个数据帧有不同的标签('a','b' 和 'A','B').
关于如何实现这一点有什么想法吗?
使用KDTree,你可以在m O(log n)
中找到最接近df1
的数学,其中n
是df2
和m
df1
.
import pandas as pd
import numpy as np
from scipy.spatial import cKDTree
df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})
def spatial_merge_NN(df1, df2, xyz=['A', 'B']):
''' Add features from df2 to df1, taking closest point '''
tree = cKDTree(df2[xyz].values)
dists, indices = tree.query(df1[['a','b']].values, k=1)
fts = [c for c in df2.columns]
for c in fts:
df1[c] = df2[c].values[indices]
return df1
df_new = spatial_merge_NN(df1, df2, ['A', 'B'])
# a b A B
# 0 1.2345 4.123 1.2346 4.1232
# 1 2.2345 5.123 2.2343 5.1239
# 2 3.2345 6.123 2.2343 5.1239
它放置一个数据帧常量(在本例中为 df1
)并遍历 df2
并从 d2
中找到最接近的对并添加该行。