Необходимо объединить два pandas кадра данных, используя два столбца широта и долгота - PullRequest
1 голос
/ 06 апреля 2020

это мой фрейм данных № 1: названия городов с широтой и долготой

df1 = {"city":['delhi','new york','london','paris','chennai'],"lat":[12.23,22.444,23.233,45.32,34.22],"long":[11.22,22.332,34.23,55.23,24.22]

это фрейм данных № 2: названия стран с широтой и долготой

df2 = pd.DataFrame({"country":['India','US','UK','France','India'],"lat":[12.13,22.54,22.33,45.32,34.22],"long":[11.12,22.132,34.23,54.23,24.22]})

Мне нужно сопоставьте эти два столбца lat и long, чтобы объединить эти две таблицы. проблема в том, что значения lat и long не совпадают точно, а значения равны + или - 0,1 или 0,2. (если совпадает, я могу использовать опцию pd.merge) lat и long здесь нереальны. просто пример

Ожидаемый результат:

result = pd.DataFrame({"city":['delhi','new york','london','paris','chennai'],"country":['India','US','UK','France','India'],"lat":[12.13,22.54,22.33,45.32,34.22],"long":[11.12,22.132,34.23,54.23,24.22]})

Каков наилучший подход к объединению этих таблиц?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2020

Geo pandas можно использовать здесь.

При условии, что у вас есть границы стран в качестве полигонов, вы можете использовать пространственные объединения .

В вашем вопросе вы сводите страны к отдельным точкам, которые могут быть не лучшим представлением.

Пример из документации:

В пространственном соединении два геометрических объекта объединяются на основе их пространственное отношение друг к другу.

# One GeoDataFrame of countries, one of Cities.
# Want to merge so we can get each city's country.
In [11]: countries.head()
Out[11]: 


                                           geometry                   country
0  MULTIPOLYGON (((180.000000000 -16.067132664, 1...                      Fiji
1  POLYGON ((33.903711197 -0.950000000, 34.072620...                  Tanzania
2  POLYGON ((-8.665589565 27.656425890, -8.665124...                 W. Sahara
3  MULTIPOLYGON (((-122.840000000 49.000000000, -...                    Canada
4  MULTIPOLYGON (((-122.840000000 49.000000000, -...  United States of America

In [12]: cities.head()
Out[12]: 
           name                           geometry
0  Vatican City  POINT (12.453386545 41.903282180)
1    San Marino  POINT (12.441770158 43.936095835)
2         Vaduz   POINT (9.516669473 47.133723774)
3    Luxembourg   POINT (6.130002806 49.611660379)
4       Palikir  POINT (158.149974324 6.916643696)

# Execute spatial join
In [13]: cities_with_country = geopandas.sjoin(cities, countries, how="inner", op='intersects')

In [14]: cities_with_country.head()
Out[14]: 
             name                           geometry  index_right  country
0    Vatican City  POINT (12.453386545 41.903282180)          141    Italy
1      San Marino  POINT (12.441770158 43.936095835)          141    Italy
192          Rome  POINT (12.481312563 41.897901485)          141    Italy
2           Vaduz   POINT (9.516669473 47.133723774)          114  Austria
184        Vienna  POINT (16.364693097 48.201961137)          114  Austria

Если у вас нет полигонов, представляющих страны, вам нужно расширить точку, представляющую каждую страну, на область. Вы можете сделать это, используя метод буфера в Shapely , который расширяет точку на область на расстояние:

Point(0, 0).buffer(10.0),

, принимая точку в координатах [0,0] и расстояние 10.0.

2 голосов
/ 06 апреля 2020

Например, перекрестное слияние:

(df1.assign(dummy=1)
    .merge(df2.assign(dummy=1),on='dummy')
    .query('abs(lat_x-lat_y)<=0.1 and abs(long_x-long_y)<=0.2')
    .drop('dummy', axis=1)
)

Вывод:

        city   lat_x  long_x country  lat_y  long_y
0      delhi  12.230  11.220   India  12.13  11.120
6   new york  22.444  22.332      US  22.54  22.132
24   chennai  34.220  24.220   India  34.22  24.220
...