Во время долгой поездки из Екатеринбурга в Тюмень мы коротали время за классической игрой в «Города». В какой-то момент стало очевидно, что названия на букву «К» встречаются аномально часто — один только Курган всплывал в памяти десятки раз. Это наблюдение натолкнуло нас на идею: собрать полные данные с RuWiki и провести полноценное исследование топонимов России, чтобы выяснить реальную статистику букв.

Представляем пошаговый процесс нашего исследования — от парсинга до глубокой аналитики.
1. Извлечение первичных данных
Для анализа мы выбрали список городов России на ресурсе RuWiki, откуда планировали забрать не только названия, но и даты основания или первых упоминаний. Для реализации парсинга использовали связку библиотек requests и BeautifulSoup.
import requests
from bs4 import BeautifulSoup
import csv
url = "https://ru.ruwiki.ru/wiki/Список_городов_России"
resp = requests.get(url)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
table = soup.find("table")
rows = table.find_all("tr")
results = []
for row in rows[1:]:
cols = row.find_all(["td","th"])
if len(cols) >= 7:
city = cols[2].get_text(strip=True)
first_mention = cols[6].get_text(strip=True)
results.append((city, first_mention))
with open("cities_data.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Город", "Основание"])
writer.writerows(results)
print(f"Обработано {len(results)} объектов.")
2. Очистка и нормализация информации
Сырые данные из Wiki часто неоднородны: встречаются лишние пробелы, примечания и разные форматы дат (например, «XII век» или «1147 год»). Чтобы привести всё к числовому виду, мы написали функцию на основе регулярных выражений, которая конвертирует века в начальные годы соответствующих столетий.
import re
def extract_year(text):
if not isinstance(text, str):
return None
text = text.lower()
# Поиск стандартного года
year_match = re.search(r'\b(1[0-9]{3}|[5-9][0-9]{2})\b', text)
if year_match:
return int(year_match.group())
# Обработка римских цифр (веков)
century_match = re.search(r'([ivxlcdm]+)\s*век', text)
if century_match:
roman = century_match.group(1).upper()
roman_map = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
value, prev = 0, 0
for c in roman[::-1]:
curr = roman_map[c]
if curr < prev:
value -= curr
else:
value += curr
prev = curr
return (value - 1) * 100
return None
3. Диахронический анализ по историческим эпохам
Для более глубокого понимания контекста мы распределили города по ключевым историческим периодам развития страны.

Логика распределения была реализована через простую сегментацию по годам:
def get_historical_period(year):
if year is None: return None
if year < 1300: return "Древнерусское государство"
elif year < 1700: return "Московское царство"
elif year < 1917: return "Российская империя"
elif year < 1991: return "Советский период"
else: return "Постсоветская Россия"
Используя библиотеку pandas, мы сгруппировали данные, а с помощью matplotlib визуализировали интенсивность градостроительства в разные эпохи. Как выяснилось, пик появления новых городов пришелся на имперский период.

4. Алфавитный анализ названий
Вернемся к нашему исходному вопросу: какие буквы доминируют в названиях? Мы проанализировали начальные и конечные литеры каждого топонима.
import matplotlib.pyplot as plt
df["first_letter"] = df["Город"].str.strip().str.upper().str[0]
letter_counts = df["first_letter"].value_counts().sort_index()
plt.figure(figsize=(10, 6))
letter_counts.plot(kind="bar", color="skyblue")
plt.title("Распределение городов по первой букве")
plt.xlabel("Буква")
plt.ylabel("Количество городов")
plt.show()

Аналогичный расчет был проведен для последних букв названий, что подтвердило наши опасения в игре — буква «К» действительно является «ловушкой».

5. Ключевые выводы исследования
- Доминирование «К»: Эта буква — абсолютный лидер. На неё начинаются 175 городов, а заканчиваются — 404!
- Стратегия для победы: Если хотите поставить оппонента в тупик, используйте города на букву «Й». Такой город в России всего один (Йошкар-Ола), в то время как заканчиваются на «Й» целых 80 названий.
- Тезки: В ходе анализа обнаружено 27 пар городов-дубликатов с одинаковыми названиями.
- Лаконичность и масштаб: Самые короткие названия (всего 2–3 знака) — это Уфа, Ом и Як. Рекордсменами по длине (до 20 символов) стали Северодвинск, Новокузнецк и Новосибирск.




