列値のペア間の一致に基づいて2つのデータフレームをマージしようとしています。ただし、列の値は、あるデータフレームから次のデータフレームまで正確ではありません。ペアはスイス座標系を使用した座標ですが、各dfのわずかに異なる基準点から測定されます。
このstackoverflowスレッドパンダの2つの異なるデータフレームの2点間の距離を見つける方法は?関連するクエリのようですが、残念ながら私は応答を完全には理解していません。
私のデータの例:
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を使用しようとしましたが、2つの変数をキー入力できないことに気付きました。緯度と経度に基づいてこれを計算するスレッドも見ました。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)
またはこのようなものですが、この種の関数を使用して、最小距離に基づいて2つの別々のデータフレームからの座標ペアを比較および照合する方法を理解できません。実際のデータセットも約300万エントリであり、これを行うための最もメモリを消費しない方法は何でしょうか。
ライブラリを使用して距離を計算するには、統合システムを使用する必要があります。グーグルから私はあなたがepsg:21781を使用していると思います
pyproj
geopy
import pyproj, geopy.distance
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']})
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/4326
sc = 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.distance
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']})
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/4326
sc = pyproj.Proj("epsg:21781")
dc = pyproj.Proj("epsg:4326")
# pick a reference point for use in diatnace calcs
refpoint = 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 works
pd.merge_asof(df1, df2, on="distance", direction="nearest")
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加