ближайший член в двух одинаковых сетках данных со склеарном - PullRequest
1 голос
/ 24 марта 2020

У меня есть 2 кадра данных:

df1:

                    x             y        c0
2       468958.147443  4.633810e+06  1.253041
43      475516.484948  4.634928e+06  1.423767
72      475802.708042  4.635308e+06  1.294299
106     476658.696529  4.635686e+06  1.338760
133     472671.587615  4.636082e+06  1.325560
              ...           ...       ...
707923  394329.199687  5.006761e+06  1.155477
707980  409697.377813  5.006524e+06  1.223895
708570  411859.618686  5.006875e+06  1.093296
708576  413477.224756  5.006853e+06  1.161713
708695  445559.757010  5.006496e+06  1.149282

[12880 rows x 3 columns]

df2:

         kat    z0     kr             xx            yy
0        1.0  0.01  0.169  468526.696610  4.633654e+06
1        3.0  0.30  0.214  468757.270633  4.633653e+06
2        1.0  0.01  0.169  468066.930344  4.633965e+06
3        1.0  0.01  0.169  468297.494406  4.633964e+06
4        1.0  0.01  0.169  468528.058460  4.633963e+06
     ...   ...    ...            ...           ...
1287962  3.0  0.30  0.214  399566.653186  5.115395e+06
1287963  3.0  0.30  0.214  399781.023856  5.115391e+06
1287964  1.0  0.01  0.169  396570.675453  5.115753e+06
1287965  1.0  0.01  0.169  396785.035186  5.115750e+06
1287966  1.0  0.01  0.169  399571.712593  5.115703e+06

[1287967 rows x 5 columns]

Я хочу найти ближайший член df1 в пределах определенного радиуса, позволяет скажем radius=500 из df2. Затем я хочу поместить ближайшие значения c0 в df2. Если в radius=500 нет точки df1, я хочу установить c0 в 1.0 в df2. (x,y) и (xx,yy) - это плоские координаты df1 и df2 соответственно.

Желаемый результат (выборка только для первых 5 строк):

         kat    z0     kr             xx            yy  c0
0        1.0  0.01  0.169  468526.696610  4.633654e+06  1.253041
1        3.0  0.30  0.214  468757.270633  4.633653e+06  1.253041
2        1.0  0.01  0.169  468066.930344  4.633965e+06  1.0
3        1.0  0.01  0.169  468297.494406  4.633964e+06  1.0
4        1.0  0.01  0.169  468528.058460  4.633963e+06  1.0
     ...   ...    ...            ...           ...
1287962  3.0  0.30  0.214  399566.653186  5.115395e+06  ...
1287963  3.0  0.30  0.214  399781.023856  5.115391e+06  ...
1287964  1.0  0.01  0.169  396570.675453  5.115753e+06  ...
1287965  1.0  0.01  0.169  396785.035186  5.115750e+06  ...
1287966  1.0  0.01  0.169  399571.712593  5.115703e+06  ...

Я думал о преобразовании этого в шейп-файлы и работа в некотором программном обеспечении пространственных запросов. Но я считаю, что эффективное решение можно найти здесь с sklearn. Заранее спасибо!

1 Ответ

1 голос
/ 29 марта 2020

Если я правильно понимаю ваше требование, вы можете использовать scipy cKDTree. Он имеет репутацию довольно быстрого благодаря реализации C/Cython. Попробуйте проверить, поможет ли это вам.

Я использую только первые 5 строк из вашего df2 для моих df2. Мой df1 совпадает с вашим образцом df1. Я также предполагаю, что столбец c0 является последним столбцом в df1, а расстояние равно Euclidean

from scipy.spatial import cKDTree

df1_cTree = cKDTree(df1[['x','y']])
ix_arr = df1_cTree.query(df2[['xx','yy']], k=1, distance_upper_bound=500)[1]

df2['c0'] = [df1.iloc[x, -1] if x < len(df1) else 1 for x in ix_arr]

Out[438]:
   kat    z0     kr             xx         yy        c0
0  1.0  0.01  0.169  468526.696610  4633654.0  1.253041
1  3.0  0.30  0.214  468757.270633  4633653.0  1.253041
2  1.0  0.01  0.169  468066.930344  4633965.0  1.000000
3  1.0  0.01  0.169  468297.494406  4633964.0  1.000000
4  1.0  0.01  0.169  468528.058460  4633963.0  1.253041

Примечание : индекс строки 4 из df2 имеет расстояние от [468528.058460, 4633963.0] до строки 0 df1 [468958.147443, 4633810] равно 456.4926432, поэтому оно удовлетворяет условию в пределах 500. Следовательно, его c0 не должен 1, как при желаемом выходе.

...