मेरे पास इस तरह की टेबल हैं:

import pandas as pd
import numpy as np


df1 = pd.DataFrame([
    ['A', (37.55, 126.97)],
    ['B', (37.56, 126.97)],
    ['C', (37.57, 126.98)]
], columns=['STA_NM', 'COORD'])

df2 = pd.DataFrame([
    ['A-01', (37.57, 126.99)]
], columns=['ID', 'COORD'])

मैं df2 से प्रत्येक निर्देशांक लेने की कोशिश कर रहा हूं और दो निकटतम स्टेशनों (STA_NM) और df1 से प्रत्येक निर्देशांक के लिए उनकी दूरी का पता लगाने की कोशिश कर रहा हूं, फिर उन्हें df2 के नए कॉलम में जोड़ें। मैं निम्नलिखित कोड की कोशिश की:

from heapq import nsmallest
from math import cos, asin, sqrt


def dist(x, y):
    p = 0.017453292519943295
    a = 0.5 - cos((y[0] - x[0]) * p) / 2 + cos(x[0] * p) * cos(y[0] * p) * (1 - cos((y[1] - x[1]) * p)) / 2
    return 12741 * asin(sqrt(a))

def shortest(df, v):
    l_sta = []
    
    # get a list of coords
    l_coord = df['COORD'].tolist()
    
    # get the two nearest coordinates
    near_coord = nsmallest(2, l_coord, key=lambda p: dist(v, p))

    # find station names
    l_sta.append((df.loc[df['COORD'] == near_coord[0], 'STA_NM'].to_string(index=False), round(dist(near_coord[0], v) * 1000)))
    l_sta.append((df.loc[df['COORD'] == near_coord[1], 'STA_NM'].to_string(index=False), round(dist(near_coord[1], v) * 1000)))
    
    # e.g.: [('A', 700), ('B', 1000)]
    return l_sta

df2['NEAR_STA'] = df2['COORD'].map(lambda x: shortest(df1, x))

मूल डेटा में, df1 में लगभग 700 पंक्तियाँ हैं, और df2 में लगभग 55k पंक्तियाँ हैं। जब मैंने उपरोक्त कोड की कोशिश की, तो इसमें लगभग दो मिनट लग गए। क्या इसे तेज करने का कोई बेहतर तरीका है?

4
vuvugelato 16 सितंबर 2020, 17:23

1 उत्तर

सबसे बढ़िया उत्तर

आप lat/lon निर्देशांकों को अर्थ-केंद्रित, अर्थ-फिक्स्ड (ईसीईएफ) निर्देशांक में बदल सकते हैं दूरी की गणना करने से पहले (lat और lon पृथ्वी के मूल से x/y/z बन जाते हैं)। इससे आपका डिस्टेंस तेजी से काम करेगा, क्योंकि यह एकल यूक्लिडियन दूरी गणना बन जाएगा।

आप डेटाफ्रेम/लैम्ब्डा दृष्टिकोण को भी हटा सकते हैं और इसे तेज करने के लिए साइथन या सुंबा का उपयोग कर सकते हैं।

यदि आप जानते हैं कि आपके स्टेशनों का स्थानिक वितरण कैसा दिखता है, तो चीजों को गति देने का अवसर भी है। उदाहरण के लिए, यदि वे एक नियमित ग्रिड पर हैं, तो आपको केवल चार पड़ोसी स्टेशनों को देखना होगा। यदि आप जानते हैं कि आमतौर पर दूसरे से कुछ दूरी के भीतर कम से कम 2 स्टेशन होते हैं, तो आपको केवल उस दायरे में खोज करने की आवश्यकता है। अगर आपके पास ऐसी कोई पूर्व जानकारी नहीं है तो सॉरी नो ट्रिक्स।

0
Graham S 16 सितंबर 2020, 14:38