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 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/).
@@ -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/).
@@ -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"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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)