pygeokit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygeokit-0.1.0/LICENSE +25 -0
- pygeokit-0.1.0/PKG-INFO +95 -0
- pygeokit-0.1.0/README.md +77 -0
- pygeokit-0.1.0/pyproject.toml +24 -0
- pygeokit-0.1.0/setup.cfg +4 -0
- pygeokit-0.1.0/src/pygeokit/__init__.py +19 -0
- pygeokit-0.1.0/src/pygeokit/_help.py +83 -0
- pygeokit-0.1.0/src/pygeokit/core.py +764 -0
- pygeokit-0.1.0/src/pygeokit/data/admin1.csv +3866 -0
- pygeokit-0.1.0/src/pygeokit/data/cities.csv.gz +0 -0
- pygeokit-0.1.0/src/pygeokit/data/countries.csv +253 -0
- pygeokit-0.1.0/src/pygeokit.egg-info/PKG-INFO +95 -0
- pygeokit-0.1.0/src/pygeokit.egg-info/SOURCES.txt +15 -0
- pygeokit-0.1.0/src/pygeokit.egg-info/dependency_links.txt +1 -0
- pygeokit-0.1.0/src/pygeokit.egg-info/requires.txt +7 -0
- pygeokit-0.1.0/src/pygeokit.egg-info/top_level.txt +1 -0
- pygeokit-0.1.0/tests/test_pygeokit.py +118 -0
pygeokit-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 A. Osinkin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
The bundled data files (src/pygeokit/data) are derived from GeoNames
|
|
24
|
+
(https://www.geonames.org) and are licensed under CC BY 4.0
|
|
25
|
+
(https://creativecommons.org/licenses/by/4.0/).
|
pygeokit-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pygeokit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Offline geo features from lat/lon: country, cities, capitals, city types, distances, density, city structure
|
|
5
|
+
Author: A. Osinkin
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: geo,features,geonames,machine learning,latitude,longitude
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
Requires-Dist: pandas
|
|
13
|
+
Requires-Dist: scipy
|
|
14
|
+
Requires-Dist: scikit-learn
|
|
15
|
+
Provides-Extra: h3
|
|
16
|
+
Requires-Dist: h3; extra == "h3"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# pygeokit
|
|
20
|
+
|
|
21
|
+
Offline geo features from latitude / longitude for tabular ML: country, nearest and
|
|
22
|
+
main city, capitals, city types and sizes, distances, density of neighbours, ring /
|
|
23
|
+
sector / multi-core city structure, grids, and a few urban-economics formulas
|
|
24
|
+
(Reilly, Huff, Zipf). The city data is bundled, so nothing is downloaded at run time.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pip install pygeokit
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Depends only on `numpy`, `pandas`, `scipy`, `scikit-learn`. `h3` is optional (`hex_cell`).
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import pygeokit as gk
|
|
36
|
+
|
|
37
|
+
gk.help() # cheat sheet (in Russian)
|
|
38
|
+
|
|
39
|
+
X, cat = gk.make_X(df, "lat", "lon") # ready matrix + categorical columns
|
|
40
|
+
model = CatBoostRegressor(cat_features=cat).fit(X, y)
|
|
41
|
+
|
|
42
|
+
feats = gk.get_features(df, lat_col="lat", lon_col="lon") # reference features only
|
|
43
|
+
|
|
44
|
+
gk.get_country(55.75, 37.62) # 'RU'
|
|
45
|
+
gk.get_capital("RU") # {'name': 'Moscow', 'lat': ..., ...}
|
|
46
|
+
gk.get_main_city(lat, lon) # biggest city within 60 km
|
|
47
|
+
gk.get_city_type(lat, lon) # capital / region_center / ... + size class
|
|
48
|
+
gk.haversine(lat1, lon1, lat2, lon2) # km
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## What is inside
|
|
52
|
+
|
|
53
|
+
| Group | Functions |
|
|
54
|
+
|---|---|
|
|
55
|
+
| Ready matrix for CatBoost | `make_X`, `cat_columns` |
|
|
56
|
+
| Everything at once | `get_features` |
|
|
57
|
+
| Cities and countries | `get_country`, `get_country_info`, `get_capital`, `get_nearest_city`, `get_main_city`, `get_city_type`, `dist_to_capital`, `load_cities`, `load_countries` |
|
|
58
|
+
| Distances | `haversine`, `manhattan`, `bearing`, `to_km`, `travel_minutes` |
|
|
59
|
+
| Your own points | `dist_to_nearest`, `count_within` |
|
|
60
|
+
| Density / neighbours | `neighbor_features`, `oof_neighbor_features` (leak-free target stats) |
|
|
61
|
+
| City structure | `find_centers`, `center_features`, `multi_center_features`, `city_shape` (ring / sector / multi-core heuristic) |
|
|
62
|
+
| Grids and validation | `grid_cell`, `hex_cell`, `spatial_groups`, `group_stats` |
|
|
63
|
+
| Urban economics | `city_gravity`, `huff_probabilities`, `reilly_breakpoint`, `zipf_expected` |
|
|
64
|
+
|
|
65
|
+
`city_type` comes from the GeoNames feature code: `PPLC` capital, `PPLA` region
|
|
66
|
+
center, `PPLA2` district center, `PPLA3/4/5` local center, `PPLX` city section,
|
|
67
|
+
everything else settlement. `size_class`: tiny < 10k, small < 50k, medium < 100k,
|
|
68
|
+
big < 250k, large < 1M, million.
|
|
69
|
+
|
|
70
|
+
`get_country` returns the country of the nearest city, so points right on a border
|
|
71
|
+
or far out at sea can get the neighbouring country.
|
|
72
|
+
|
|
73
|
+
## Leak-free neighbour target features
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
tr_f = gk.oof_neighbor_features(train.lat, train.lon, y) # train rows
|
|
77
|
+
te_f = gk.neighbor_features(test.lat, test.lon, train.lat, train.lon, values=y)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Building from source
|
|
81
|
+
|
|
82
|
+
The data files are not stored in the repository. Build them once:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
python tools/build_data.py # downloads GeoNames dumps (~12 MB)
|
|
86
|
+
python -m pytest tests # tests use a tiny fake data set
|
|
87
|
+
python -m build
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Set `PYGEOKIT_DATA_DIR` to use your own data directory.
|
|
91
|
+
|
|
92
|
+
## Data and license
|
|
93
|
+
|
|
94
|
+
Code: MIT. City and country data: [GeoNames](https://www.geonames.org), licensed
|
|
95
|
+
under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
pygeokit-0.1.0/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# pygeokit
|
|
2
|
+
|
|
3
|
+
Offline geo features from latitude / longitude for tabular ML: country, nearest and
|
|
4
|
+
main city, capitals, city types and sizes, distances, density of neighbours, ring /
|
|
5
|
+
sector / multi-core city structure, grids, and a few urban-economics formulas
|
|
6
|
+
(Reilly, Huff, Zipf). The city data is bundled, so nothing is downloaded at run time.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
pip install pygeokit
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Depends only on `numpy`, `pandas`, `scipy`, `scikit-learn`. `h3` is optional (`hex_cell`).
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import pygeokit as gk
|
|
18
|
+
|
|
19
|
+
gk.help() # cheat sheet (in Russian)
|
|
20
|
+
|
|
21
|
+
X, cat = gk.make_X(df, "lat", "lon") # ready matrix + categorical columns
|
|
22
|
+
model = CatBoostRegressor(cat_features=cat).fit(X, y)
|
|
23
|
+
|
|
24
|
+
feats = gk.get_features(df, lat_col="lat", lon_col="lon") # reference features only
|
|
25
|
+
|
|
26
|
+
gk.get_country(55.75, 37.62) # 'RU'
|
|
27
|
+
gk.get_capital("RU") # {'name': 'Moscow', 'lat': ..., ...}
|
|
28
|
+
gk.get_main_city(lat, lon) # biggest city within 60 km
|
|
29
|
+
gk.get_city_type(lat, lon) # capital / region_center / ... + size class
|
|
30
|
+
gk.haversine(lat1, lon1, lat2, lon2) # km
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## What is inside
|
|
34
|
+
|
|
35
|
+
| Group | Functions |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Ready matrix for CatBoost | `make_X`, `cat_columns` |
|
|
38
|
+
| Everything at once | `get_features` |
|
|
39
|
+
| Cities and countries | `get_country`, `get_country_info`, `get_capital`, `get_nearest_city`, `get_main_city`, `get_city_type`, `dist_to_capital`, `load_cities`, `load_countries` |
|
|
40
|
+
| Distances | `haversine`, `manhattan`, `bearing`, `to_km`, `travel_minutes` |
|
|
41
|
+
| Your own points | `dist_to_nearest`, `count_within` |
|
|
42
|
+
| Density / neighbours | `neighbor_features`, `oof_neighbor_features` (leak-free target stats) |
|
|
43
|
+
| City structure | `find_centers`, `center_features`, `multi_center_features`, `city_shape` (ring / sector / multi-core heuristic) |
|
|
44
|
+
| Grids and validation | `grid_cell`, `hex_cell`, `spatial_groups`, `group_stats` |
|
|
45
|
+
| Urban economics | `city_gravity`, `huff_probabilities`, `reilly_breakpoint`, `zipf_expected` |
|
|
46
|
+
|
|
47
|
+
`city_type` comes from the GeoNames feature code: `PPLC` capital, `PPLA` region
|
|
48
|
+
center, `PPLA2` district center, `PPLA3/4/5` local center, `PPLX` city section,
|
|
49
|
+
everything else settlement. `size_class`: tiny < 10k, small < 50k, medium < 100k,
|
|
50
|
+
big < 250k, large < 1M, million.
|
|
51
|
+
|
|
52
|
+
`get_country` returns the country of the nearest city, so points right on a border
|
|
53
|
+
or far out at sea can get the neighbouring country.
|
|
54
|
+
|
|
55
|
+
## Leak-free neighbour target features
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
tr_f = gk.oof_neighbor_features(train.lat, train.lon, y) # train rows
|
|
59
|
+
te_f = gk.neighbor_features(test.lat, test.lon, train.lat, train.lon, values=y)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Building from source
|
|
63
|
+
|
|
64
|
+
The data files are not stored in the repository. Build them once:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
python tools/build_data.py # downloads GeoNames dumps (~12 MB)
|
|
68
|
+
python -m pytest tests # tests use a tiny fake data set
|
|
69
|
+
python -m build
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Set `PYGEOKIT_DATA_DIR` to use your own data directory.
|
|
73
|
+
|
|
74
|
+
## Data and license
|
|
75
|
+
|
|
76
|
+
Code: MIT. City and country data: [GeoNames](https://www.geonames.org), licensed
|
|
77
|
+
under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pygeokit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Offline geo features from lat/lon: country, cities, capitals, city types, distances, density, city structure"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{name = "A. Osinkin"}]
|
|
14
|
+
keywords = ["geo", "features", "geonames", "machine learning", "latitude", "longitude"]
|
|
15
|
+
dependencies = ["numpy", "pandas", "scipy", "scikit-learn"]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
h3 = ["h3"]
|
|
19
|
+
|
|
20
|
+
[tool.setuptools.packages.find]
|
|
21
|
+
where = ["src"]
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.package-data]
|
|
24
|
+
pygeokit = ["data/*.csv", "data/*.csv.gz"]
|
pygeokit-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""pygeokit - offline geo features from latitude / longitude.
|
|
2
|
+
|
|
3
|
+
import pygeokit as gk
|
|
4
|
+
gk.help() # cheat sheet
|
|
5
|
+
feats = gk.get_features(df, lat_col="lat", lon_col="lon")
|
|
6
|
+
"""
|
|
7
|
+
from ._help import help
|
|
8
|
+
from .core import (
|
|
9
|
+
bearing, cat_columns, center_features, city_shape, city_gravity, count_within, dist_to_capital,
|
|
10
|
+
dist_to_nearest, find_centers, get_capital, get_city_type, get_country,
|
|
11
|
+
get_country_info, get_features, get_main_city, get_nearest_city, grid_cell,
|
|
12
|
+
group_stats, haversine, hex_cell, huff_probabilities, load_cities,
|
|
13
|
+
load_countries, make_X, manhattan, multi_center_features, neighbor_features,
|
|
14
|
+
oof_neighbor_features, reilly_breakpoint, spatial_groups, to_km,
|
|
15
|
+
travel_minutes, zipf_expected,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
__all__ = [n for n in dir() if not n.startswith("_")]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
HELP = r"""
|
|
2
|
+
pygeokit - шпаргалка import pygeokit as gk; gk.help()
|
|
3
|
+
Везде: lat = широта, lon = долгота (в градусах). Принимаются числа, массивы, Series.
|
|
4
|
+
Расстояния в км. Подробности по функции: help(gk.get_features)
|
|
5
|
+
|
|
6
|
+
== ГОТОВЫЙ X ДЛЯ CATBOOST ==================================================
|
|
7
|
+
X_tr, cat = gk.make_X(train.drop(columns=["target"]), "lat", "lon")
|
|
8
|
+
X_te, _ = gk.make_X(test, "lat", "lon", ref=train) # плотность считать по train
|
|
9
|
+
model = CatBoostRegressor(cat_features=cat).fit(X_tr, y)
|
|
10
|
+
возвращает ДВЕ вещи: X и список категориальных колонок.
|
|
11
|
+
X = копия твоего X + все гео-признаки (справочник, положение в городе,
|
|
12
|
+
ячейки сетки, плотность точек). Таргет не используется, утечки нет.
|
|
13
|
+
|
|
14
|
+
== ВСЁ СРАЗУ (только справочные признаки) ==================================
|
|
15
|
+
feats = gk.get_features(df, lat_col="lat", lon_col="lon") # ~30 признаков
|
|
16
|
+
df = pd.concat([df, feats], axis=1)
|
|
17
|
+
страна, регион, ближайший город, главный город рядом (население, тип, размер,
|
|
18
|
+
ранг в стране), расстояния до столицы / центра региона / города 100к / 1 млн,
|
|
19
|
+
число городов и население в 10/50/100 км, "притяжение" крупных городов.
|
|
20
|
+
Текстовые колонки -> в cat_features CatBoost.
|
|
21
|
+
|
|
22
|
+
== СПРАВОЧНИК ГОРОДОВ И СТРАН =============================================
|
|
23
|
+
gk.get_country(lat, lon) -> 'RU' (код страны)
|
|
24
|
+
gk.get_country_info('RU') -> dict (столица, население, площадь, ...)
|
|
25
|
+
gk.get_capital('RU') -> dict name/lat/lon/population
|
|
26
|
+
gk.get_nearest_city(lat, lon, min_population=0, k=1, types=None)
|
|
27
|
+
gk.get_main_city(lat, lon, radius_km=60) # самый крупный город в радиусе
|
|
28
|
+
gk.get_city_type(lat, lon) -> city_type + size_class
|
|
29
|
+
city_type : capital / region_center / district_center / local_center /
|
|
30
|
+
settlement / city_section
|
|
31
|
+
size_class: tiny <10k, small <50k, medium <100k, big <250k, large <1M, million
|
|
32
|
+
gk.dist_to_capital(lat, lon)
|
|
33
|
+
gk.load_cities(min_population=0), gk.load_countries() # сырые таблицы
|
|
34
|
+
|
|
35
|
+
== РАССТОЯНИЯ =============================================================
|
|
36
|
+
gk.haversine(lat1, lon1, lat2, lon2) # км по сфере
|
|
37
|
+
gk.manhattan(...) # "по кварталам"
|
|
38
|
+
gk.bearing(...) # направление, 0=север, 90=восток
|
|
39
|
+
gk.to_km(lat, lon) # -> x,y в км (для KMeans/HDBSCAN/евклида)
|
|
40
|
+
gk.travel_minutes(km, mode="walk") # walk 5 км/ч, bike 15, car 30
|
|
41
|
+
15-минутный город: пешком 15 мин ~ 1.25 км
|
|
42
|
+
|
|
43
|
+
== СВОИ ТОЧКИ (метро, магазины, конкуренты) ===============================
|
|
44
|
+
gk.dist_to_nearest(lat, lon, ref_lat, ref_lon, k=1)
|
|
45
|
+
gk.count_within(lat, lon, ref_lat, ref_lon, radius_km=1.25)
|
|
46
|
+
|
|
47
|
+
== ПЛОТНОСТЬ И СОСЕДИ =====================================================
|
|
48
|
+
gk.neighbor_features(lat, lon) # сколько точек рядом
|
|
49
|
+
gk.neighbor_features(lat, lon, ref_lat, ref_lon, values=v) # + sum/mean/std v
|
|
50
|
+
!!! если values = таргет:
|
|
51
|
+
tr_f = gk.oof_neighbor_features(tr.lat, tr.lon, y) # трейн, без утечки
|
|
52
|
+
te_f = gk.neighbor_features(te.lat, te.lon, tr.lat, tr.lon, values=y) # тест
|
|
53
|
+
|
|
54
|
+
== УСТРОЙСТВО ГОРОДА (кольца / секторы / несколько ядер) ==================
|
|
55
|
+
c = gk.find_centers(lat, lon, weight=turnover, n_centers=3) # ядра по данным
|
|
56
|
+
gk.center_features(lat, lon, c.lat[0], c.lon[0]) # расстояние, кольцо, сектор
|
|
57
|
+
gk.multi_center_features(lat, lon, c) # до каждого ядра + ближайшее
|
|
58
|
+
центр из справочника: m = gk.get_main_city(lat, lon)
|
|
59
|
+
gk.center_features(lat, lon, m.lat.values, m.lon.values)
|
|
60
|
+
|
|
61
|
+
тип города из лекции (кольцевой / секторный / несколько ядер), ЭВРИСТИКА:
|
|
62
|
+
gk.city_shape(lat, lon, weight=None, group=city_id) # строка на город:
|
|
63
|
+
shape = ring / sector / multi_core + elongation, core2_ratio, core_sep, ...
|
|
64
|
+
|
|
65
|
+
== СЕТКИ И ВАЛИДАЦИЯ ======================================================
|
|
66
|
+
gk.grid_cell(lat, lon, size_km=1) # id квадрата -> категориальный признак
|
|
67
|
+
gk.hex_cell(lat, lon, res=8) # H3 (нужен pip install h3)
|
|
68
|
+
gk.spatial_groups(lat, lon, size_km=50) # groups для GroupKFold
|
|
69
|
+
gk.group_stats(df, by="cell", value="amount") # n, sum, mean(ср. чек), median...
|
|
70
|
+
|
|
71
|
+
== ЭКОНОМИКА ГОРОДОВ ======================================================
|
|
72
|
+
gk.city_gravity(lat, lon) # притяжение крупных городов
|
|
73
|
+
gk.huff_probabilities(dist, attractiveness) # вероятность выбрать каждый центр
|
|
74
|
+
gk.reilly_breakpoint(dist_ab, pop_a, pop_b) # граница зон притяжения A и B
|
|
75
|
+
gk.zipf_expected(largest_pop, rank) # закон Ципфа: pop = max / rank
|
|
76
|
+
|
|
77
|
+
Данные: GeoNames (geonames.org), лицензия CC BY 4.0.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def help():
|
|
82
|
+
"""Print the cheat sheet (in Russian)."""
|
|
83
|
+
print(HELP)
|