根据列值对之间的最近匹配合并两个数据帧

我正在尝试根据列值对之间的匹配项合并两个数据框。但是,从一个数据帧到下一个数据帧的列值并不准确。这些对是使用瑞士坐标系的坐标,但在每个 df 中从略微不同的参考点测量。


我的数据示例:

df1 = pd.DataFrame({'Ecode': [2669827.294, 2669634.483, 2669766.266, 2669960.683],

                    'Ncode': [1261034.528, 1262412.587, 1261209.646, 1262550.374],

                    'shape': ['square', 'square', 'triangle', 'circle']})


df1

     Ecode            Ncode          shape

0   2669827.294     1261034.528     square

1   2669634.483     1262412.587     square

2   2669766.266     1261209.646     triangle

3   2669960.683     1262550.374     circle



df2 = pd.DataFrame({'CoorE': [2669636, 2669765, 2669827, 2669961],

                    'CoorN': [1262413, 1261211, 1261032, 1262550],

                    'color': ['purple', 'blue', 'blue', 'yellow']})


df2

     CoorE       CoorN      color

0   2669636     1262413     purple

1   2669765     1261211     blue

2   2669827     1261032     blue

3   2669961     1262550     yellow


我有我想比较的数据,位于两组坐标(例如“形状”和“颜色”)。我想要的结果与最接近匹配的列对匹配:


     CoorE       CoorN      color   shape

0   2669636     1262413     purple  square

1   2669765     1261211     blue    triangle

2   2669827     1261032     blue    square

3   2669961     1262550     yellow  circle

有没有办法做到这一点?我曾尝试使用 merge_asof 但意识到它不能键控两个变量。我还看到线程根据纬度和经度计算这个。我可以编写一个函数,将 CoorE/CoorN 和 Ecode/Ncode 视为 x/y 坐标,并计算一对坐标之间的距离(可能有更好的方法,但我是新手):


import math  

def calculateDistance(x1,y1,x2,y2):  

     dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)  

     return dist  

print calculateDistance(x1, y1, x2, y2)

或类似的东西,但无法弄清楚如何使用这种函数根据最小距离比较和匹配来自两个独立数据帧的坐标对。真实的数据集也有大约 300 万个条目,我想知道执行此操作的内存占用最少的方法是什么。


摇曳的蔷薇
浏览 161回答 1
1回答

慕勒3428872

要使用库来计算距离,您需要在统一系统上。来自谷歌,我相信你正在使用epsg:21781首先使用标准化坐标系pyproj做颜色和形状的笛卡尔积使用计算这些之间的距离geopy您现在可以选择您想要的结果行。举个例子,我在按颜色和形状分组时采取了最近的做法import pyproj, geopy.distancedf1 = pd.DataFrame({'Ecode': [2669827.294, 2669634.483, 2669766.266, 2669960.683],                    'Ncode': [1261034.528, 1262412.587, 1261209.646, 1262550.374],                    'shape': ['square', 'square', 'triangle', 'circle']})df2 = pd.DataFrame({'CoorE': [2669636, 2669765, 2669827, 2669961],                    'CoorN': [1262413, 1261211, 1261032, 1262550],                    'color': ['purple', 'blue', 'blue', 'yellow']})# assuming this co-ord system https://epsg.io/21781 then mapping to https://epsg.io/4326sc = pyproj.Proj("epsg:21781")dc = pyproj.Proj("epsg:4326")df1 = df1.assign(    shape_gps=lambda x: x.apply(lambda r: pyproj.transform(sc, dc, r["Ecode"], r["Ncode"]), axis=1))df2 = df2.assign(    color_gps=lambda x: x.apply(lambda r: pyproj.transform(sc, dc, r["CoorE"], r["CoorN"]), axis=1))(df1     .assign(foo=1)     .merge(df2.assign(foo=1), on="foo")     .assign(distance=lambda x: x.apply(lambda r:                                         geopy.distance.geodesic(r["color_gps"], r["shape_gps"]).km, axis=1))     .sort_values("distance") .groupby(["color","shape"]).agg({"distance":"first","CoorE":"first","CoorN":"first"}))为最近的合并更新如果你选择一个参考点来计算距离,你会得到你想要的。import pyproj, geopy.distancedf1 = pd.DataFrame({'Ecode': [2669827.294, 2669634.483, 2669766.266, 2669960.683],                    'Ncode': [1261034.528, 1262412.587, 1261209.646, 1262550.374],                    'shape': ['square', 'square', 'triangle', 'circle']})df2 = pd.DataFrame({'CoorE': [2669636, 2669765, 2669827, 2669961],                    'CoorN': [1262413, 1261211, 1261032, 1262550],                    'color': ['purple', 'blue', 'blue', 'yellow']})# assuming this co-ord system https://epsg.io/21781 then mapping to https://epsg.io/4326sc = pyproj.Proj("epsg:21781")dc = pyproj.Proj("epsg:4326")# pick a reference point for use in diatnace calcsrefpoint = pyproj.transform(sc, dc, df1.loc[0,["Ecode"]][0], df1.loc[0,["Ncode"]][0])df1 = df1.assign(    shape_gps=lambda x: x.apply(lambda r: pyproj.transform(sc, dc, r["Ecode"], r["Ncode"]), axis=1),    distance=lambda x: x.apply(lambda r: geopy.distance.geodesic(refpoint, r["shape_gps"]).km, axis=1),).sort_values("distance")df2 = df2.assign(    color_gps=lambda x: x.apply(lambda r: pyproj.transform(sc, dc, r["CoorE"], r["CoorN"]), axis=1),    distance=lambda x: x.apply(lambda r: geopy.distance.geodesic(refpoint, r["color_gps"]).km, axis=1),).sort_values("distance")# no cleanup of columns but this workspd.merge_asof(df1, df2, on="distance", direction="nearest")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python