Фінальний проєкт: Аналіз даних переписів села Дунаєць за 1778 й 1897 роки¶
Єфімова Оксана
Початок роботи¶
Цей файл представляє собою аналіз даних переписів населення села Дунаєць Чернігівської губернії за 1778 та 1897 роки. Для роботи я використала бібліотеки, з якими ми працювали протягом курсу а також plotly.express, тому його необхідно завантажити.
%pip install plotly.express
Requirement already satisfied: plotly.express in ./.venv/lib/python3.12/site-packages (0.4.1) Requirement already satisfied: pandas>=0.20.0 in ./.venv/lib/python3.12/site-packages (from plotly.express) (2.2.3) Requirement already satisfied: plotly>=4.1.0 in ./.venv/lib/python3.12/site-packages (from plotly.express) (6.2.0) Requirement already satisfied: statsmodels>=0.9.0 in ./.venv/lib/python3.12/site-packages (from plotly.express) (0.14.5) Requirement already satisfied: scipy>=0.18 in ./.venv/lib/python3.12/site-packages (from plotly.express) (1.16.0) Requirement already satisfied: patsy>=0.5 in ./.venv/lib/python3.12/site-packages (from plotly.express) (1.0.1) Requirement already satisfied: numpy>=1.11 in ./.venv/lib/python3.12/site-packages (from plotly.express) (2.2.6) Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas>=0.20.0->plotly.express) (2.9.0.post0) Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas>=0.20.0->plotly.express) (2025.2) Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas>=0.20.0->plotly.express) (2025.2) Requirement already satisfied: narwhals>=1.15.1 in ./.venv/lib/python3.12/site-packages (from plotly>=4.1.0->plotly.express) (1.42.1) Requirement already satisfied: packaging in ./.venv/lib/python3.12/site-packages (from plotly>=4.1.0->plotly.express) (25.0) Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas>=0.20.0->plotly.express) (1.17.0) [notice] A new release of pip is available: 23.2.1 -> 25.1.1 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages.
Імпорт усі необхідних бібліотек
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import altair as alt
import plotly.express as px
Дані про мешканців села 1778 року імпортовано в DataFrame, створено копію для роботи, змінено формат назв стовпців для зручності аналізу.
pop_1778 = pd.read_csv('2.2_Дунаєць_1778(2).xlsx - База.csv')
pop_1778 = pop_1778.copy()
pop_1778.rename(columns={'Unnamed: 10': 'rus_surname', 'Unnamed: 15': 'age', 'Unnamed: 6': 'men', 'Unnamed: 14': 'status', 'Unnamed: 2': 'family_num', 'Unnamed: 11': 'family_status_rus'}, inplace=True)
pop_1778
| Unnamed: 0 | Unnamed: 1 | family_num | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | men | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | rus_surname | family_status_rus | Unnamed: 12 | Unnamed: 13 | status | age | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1 | Аркуш | NaN | NaN | NaN | Число людей наскрізне | NaN | Число людей джерело | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | NaN | ID наскрізна | ID домогосподарство | Двори джерело | Чоловіки | Жінки | Чоловіки | Жінки | Імʼя | По-батькові | Прізвище | Родиний статус | Категорія | Клас | Соціальний статус | Вік | Був на сповіді | Не був | Не був за малолітством |
| 3 | 445 | 1 | 1 | 1 | 1 | NaN | 1 | NaN | Федор | Кондратьев | Лукашевич | господар | nuclear | 3b | духовные | 44 | х | NaN | NaN |
| 4 | NaN | 2 | NaN | NaN | NaN | 1 | NaN | 1 | Варвара | Симева | NaN | жена | NaN | NaN | духовные | 35 | х | NaN | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1595 | NaN | 1593 | 104 | 12 | 824 | NaN | 236 | NaN | Леонтий | Афанасиев | NaN | двоюродный брат Александра | nuclear | 3a | бездворные | 25 | х | NaN | NaN |
| 1596 | NaN | 1594 | NaN | NaN | NaN | 770 | NaN | 222 | Мотрона | Михайлова | NaN | жена его | NaN | NaN | бездворные | 22 | х | NaN | NaN |
| 1597 | NaN | 1595 | 105 | 13 | 825 | NaN | 237 | NaN | Герасим | Фомик | Мерник | господар | nuclear | 3b | бездворные | 43 | х | NaN | NaN |
| 1598 | NaN | 1596 | NaN | NaN | NaN | 771 | NaN | 223 | Агафия | Максимова | NaN | жена его | NaN | NaN | бездворные | 42 | х | NaN | NaN |
| 1599 | NaN | 1597 | NaN | NaN | 826 | NaN | 238 | NaN | Лукьян | NaN | NaN | NaN | NaN | NaN | бездворные | 14 | х | NaN | NaN |
1600 rows × 19 columns
Аналогічну операцію проведено з іншим датасетом
data_1897 = pd.read_csv('2.1_Дунаєць.xlsx - База листов.csv')
pop_1897 = pd.read_csv('2.1_Дунаєць.xlsx - База людей.csv')
pop_1897 = pop_1897.copy()
pop_1897.rename(columns = {'Пол': 'gender', 'Возраст': 'age'}, inplace = True)
pop_1897
| Кто заполнял базу | ID строки в базе | List ID | Link | ID Домохозяйствао | ID жилец | ФИО | gender | Глава хозяйства и глава семьи | age | ... | Здесь ли обыкновенно проживает | Отметка об отсуствии | Вероисповедание | Родной язык | Умеет ли читать | Обучение | Профессия главное | Профессия вспомогательное | Положение по воинской повинности | Примітки | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Podhorna | 1.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 1.0 | Krasovskij Pantelejmon Ivanovich | m | husband | 32 | ... | 1 | NaN | orthodox | ukr | 1.0 | rural school | farmer | NaN | Nizhnij chin zapasu | NaN |
| 1 | Podhorna | 2.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 2.0 | Krasovskaya Stefanida Artemieva | f | wife | 28 | ... | 1 | NaN | orthodox | ukr | 0.0 | NaN | farmer with husband | NaN | NaN | NaN |
| 2 | Podhorna | 3.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 3.0 | Krasovskaya Anna Pantelejmonova | f | daughter | 5 | ... | 1 | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN |
| 3 | Podhorna | 4.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 4.0 | Krasovskij Stefan Pantelejmonov | m | son | 1 | ... | 1 | NaN | orthodox | ukrm | 0.0 | NaN | with father | NaN | NaN | NaN |
| 4 | Podhorna | 5.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 5.0 | Krasovskij Ivan Kondratov | m | father | 70 | ... | 1 | NaN | orthodox | ukr | 0.0 | NaN | with son | NaN | NaN | Slep na oba hlaza 10 let nazad |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1547 | Podhorna | 1548.0 | F.132.Op.1.Spr.1343. Арк.550-551 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 261.0 | 6.0 | Gricunov Mikhail Sergeev | m | son | 3 | ... | 1 | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN |
| 1548 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1549 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1550 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1551 | * - В оригінальному джерелі ячейка "мова" була... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1552 rows × 25 columns
Вікова структура¶
Порівняння вікової структури населення¶
Для початку було проведено аналіз вікової структури населення, згідно з даними обох переписів. Колонки з обох датасетів були перейменовані таким чином, щоб ними можна було однаково кооперувати. З цією ж метою створено колонку gender у pop_1778, щоб вона була аналогічна розподілу на статі в pop_1897. Також необхідно було почистити перші рядки датасету перепису 1778 року, оскільки його структура дещо відрізняється від іншого.
pop_1778['gender'] = pop_1778.iloc[3:].men.apply(lambda x: 'm' if pd.notna(x) else 'f')
ages_1778 = pop_1778.age.iloc[3:].dropna()
ages_1897 = pop_1897.age.dropna()
Наступним було створено окремий датафрейм, який містить лише стовпці з віком, додамо стовпець із роком для кожного значення і поєднано датафрейми за допомогою pd.concat().
ages_1778 = ages_1778.to_frame(name='age')
ages_1778['year'] = '1778'
ages_1897 = ages_1897.to_frame(name='age')
ages_1897['year'] = '1897'
ages_concat = pd.concat([ages_1778, ages_1897])
ages_concat
| age | year | |
|---|---|---|
| 3 | 44 | 1778 |
| 4 | 35 | 1778 |
| 5 | 17 | 1778 |
| 6 | 15 | 1778 |
| 7 | 14 | 1778 |
| ... | ... | ... |
| 1543 | 30 | 1897 |
| 1544 | 9 | 1897 |
| 1545 | 7 | 1897 |
| 1546 | 5 | 1897 |
| 1547 | 3 | 1897 |
3142 rows × 2 columns
Тепер отримано датафрейм, який складається з віку осіб, де половина відноситься до 1778 року, а інша -- до 1897. Це дає змогу побудувати гістограму. Для цього я використовую бібліотеку Altair. Гістограма побудована таким чином, що на кожному відрізку можна дослідити різницю між обома переписами, оскільки графіки накладені.
alt.Chart(ages_concat).mark_bar(opacity=0.5,binSpacing=0).encode(alt.X('age:Q', title = 'Вік').bin(maxbins=20),alt.Y('count()', title = 'Кількість').stack(None), alt.Color('year:N', title='Рік')).properties(width=600,height=400,title='Розподіл віку у 1778 та 1897 роках')
Результат показує, що у 1778 році народжуваність була досить високою, а тривалість життя низькою, що є нормою для цього часу. Цей період в с.Дунаєць припав на поступову ліквідацію козацтва та до запровадження кріпацтва для селян. Можливою причиною спаду частки дитячого населення, а саме осіб від 5 до 15 років може бути дитяча смертність, оскільки ця категорія найбільш вразлива до хвороб. Щодо 1897 року, то спостерігається помітне зростання тривалості життя, графік є плавнішим, ніж попередній, народжуваність дещо впала, пояснювати це може той факт, що після відміни кріпосного права, землі не вистачало на всіх, тому це було б не вигідно для сімей. Імовірно, це могло би бути причиною різкого спаду молодого населення (20-25 років), які мігрували в пошуках кращого життя.
Порівняння статевого співвідношення вікових груп¶
Отримавши такі дані, було проведено ще віковий розподіл населення за статтю. Для цього було розроблено функцію population_pyramid_builder(df, year), де df -- датафрейм, який буде аналізуватися, year -- рік, потрібен для формування заголовка до піраміди. Оскільки побудова пірамід для обох років потребує багато повторюваних операцій, функції можуть скоротити довжину коду і підвищити читабельність.
def age_group(age):
if pd.isna(age):
return None
age_num = pd.to_numeric(age, errors='coerce')
if pd.isna(age_num):
return None
elif isinstance(age, str) and any(term in age for term in ['month', 'months', 'day', 'days', 'week', 'weeks']) or age_num < 5:
return '0-4'
elif isinstance(age, str) and any(term in age for term in ['month', 'months', 'day', 'days', 'week', 'weeks']) or 4 < age_num < 10:
return '5-9'
elif age_num % 10 <= 4:
lower = (age_num // 10) * 10
return f'{lower}-{lower + 4}'
else:
lower = (age_num // 10) * 10 + 5
return f'{lower}-{lower + 4}'
pop_1778['age_group'] = pop_1778['age'].apply(age_group)
pop_1778 = pop_1778[pop_1778['age_group'].notna()].copy()
pop_1897['age_group'] = pop_1897['age'].apply(age_group)
pop_1897 = pop_1897[pop_1897['age_group'].notna()].copy()
unique_ages_list = []
unique_ages_list.append(pop_1778['age_group'].dropna().drop_duplicates().to_list())
unique_ages_list.append(pop_1897['age_group'].dropna().drop_duplicates().to_list())
common_order = max(unique_ages_list, key = len)
common_order = sorted(common_order, key=lambda x: int(x.split('-')[0]), reverse=True)
common_order_s = pd.Series(common_order)
def population_pyramid_builder(df, year):
df['age_group_lower'] = df['age_group'].apply(lambda x: x.split('-')[0] if isinstance(x, str) else None)
df['age_group_lower'] = df['age_group_lower'].str.strip()
df = df.sort_values(by = 'age_group_lower', key=lambda x: pd.to_numeric(x), ascending = False)
df.drop(columns='age_group_lower', inplace=True)
males = df[(df['gender'] == 'm')]
females = df[(df['gender'] == 'f')]
male = alt.Chart(males).mark_bar(color='#1f77b4').encode(x=alt.X('count(age_group):Q', title = 'Чоловіки', scale=alt.Scale(reverse=True, domainMax=120)),y=alt.Y("age_group:O", sort=common_order, axis=None), tooltip = alt.Tooltip(['count(age_group)'], title = "Кількість"))
middle = alt.Chart(common_order_s.to_frame(name='age_group')).mark_text().encode(y=alt.Y('age_group:O', sort=common_order, axis=None),text=alt.Text('age_group:O'))
female = alt.Chart(females).mark_bar(color = '#e377c2').encode(x=alt.X('count(age_group):Q', title = 'Жінки'), y= alt.Y("age_group:O", sort = common_order, axis=None), tooltip = alt.Tooltip(['count(age_group)'], title = "Кількість"))
gender_pyramid = alt.concat(male, middle, female, spacing=1).resolve_scale(y='shared').properties(title=alt.TitleParams(text=f'Віковий розподіл населення за статтю ({year})', anchor='middle'))
return gender_pyramid
pyramid_1778 = population_pyramid_builder(pop_1778, 1778)
pyramid_1897 = population_pyramid_builder(pop_1897, 1897)
alt.hconcat(pyramid_1778, pyramid_1897).resolve_scale(y='shared')
Представлені результати показують, що у 1778 році частка дівчат віком від 5 до 9 років є удвічі меншою ніж віком до 4 років, що може вказувати на високий рівень дитячої смертності, особливо серед дівчат. У піраміді за 1897 рік помітна істотна різниця між часткою хлопчиків віком до 4 років та дівчатками того ж віку. Можливою причиною цьому може бути вразливість до хвороб. Загалом же піраміда є доволі симетричною і вказує на демографічну стабільність.
Соціальна структура¶
Порівняння соціальної структури сімей¶
Село Дунаєць, за писемними джерелами, засноване в першій половині 17 ст. глухівським козаком Радьком, та заселено було в основному вільними козаками. (вікіпедія)
Як уже зазначалося в контексті ліквідації козацького устрою, було проведено аналіз соціальної структури сімей за обома переписами. У базі листів перепису 1778 року присутні такі верстви населення, як військові, духовенство та посполиті й бездвірні. Проаналізувавши дані з документа "2.2_Дунаєць_1778(2).xlsx - Пояснення та фінальні таблиці.csv", стає зрозуміло, що з 35 сімей, зарахованих до категорії військових, 34 -- мають козацький статус, а 1 -- родина відставного майора. Для підтвердження результатів було зроблено перевірку кількості сімей зі статусом "військові".
pop_1778[pop_1778['status'] == 'военные']['family_num'].value_counts().sum()
np.int64(35)
Що й збігається з результатами документу "2.2.2_Структура родини Дунаєць_1778.xlsx - Военные.csv"
Натомість база листів 1897 року поділяє родини на наступні групи: козаки, духовенство, дворяни й селяни. Така різниця між даними двох переписів цілком має сенс, адже за століття відбулися значні зміни у соціальному становищі імперії. З метою кращого порівняння між результатами розподілу, було вирішено виокремити родину майора в окремий датафрейм, а решту позначити як козаків. Іншф категорії звести до відповідних не можна, тому вони залишуться початковими.
cossacks_1778 = pd.read_csv('2.2.2_Структура родини Дунаєць_1778.xlsx - Военные.csv')
cossacks_1778.at[5, 'Кількість'] -= 1
major_1778 = cossacks_1778.copy()
major_1778[['Кількість', '%', '% кожного класу', 'Усього по категоріях']] = 0
major_1778.at[5, 'Кількість'] = 1
dukhovni_1778 = pd.read_csv('2.2.2_Структура родини Дунаєць_1778.xlsx - Духовные.csv')
pospolyti_1778 = pd.read_csv('2.2.2_Структура родини Дунаєць_1778.xlsx - Посполитые+бездворные.csv')
total_1778 = pd.read_csv('2.2.2_Структура родини Дунаєць_1778.xlsx - Total.csv')
church_data_1778 = pd.read_csv('2.2_Дунаєць_1778(2).xlsx - Пояснення та фінальні таблиці.csv')
cossacks_1897 = pd.read_csv('2.1.1_Структура родини Дунаєць_1897.xlsx - Cossacks.csv')
dukhovni_1897 = pd.read_csv('2.1.1_Структура родини Дунаєць_1897.xlsx - Dukhovnogo.csv')
nobels_1897 = pd.read_csv('2.1.1_Структура родини Дунаєць_1897.xlsx - Nobles+imenuyushchijsya dvoryan.csv')
peasants_1897 = pd.read_csv('2.1.1_Структура родини Дунаєць_1897.xlsx - Peasant-owner.csv')
total_1897 = pd.read_csv('2.1.1_Структура родини Дунаєць_1897.xlsx - Total.csv')
Функція status_filter(df, cat) була створена, для того щоб створити окремі датасети які мають спільну частину по стовпцях "Категорія" і "Клас" та відрізняються за кількістю, яка позначена відповідним статусом, переданим cat. Такий підхід дозволяє уникнути переназивання значень при подальшій візуалізації.
def status_filter(df, cat):
df = df.copy()
df['Клас'] = df['Клас'].str[2:]
df_count = df[['Категорія', 'Клас', 'Кількість']].iloc[:-1]
df_count.rename(columns = {'Кількість': cat}, inplace = True)
return df_count
cossacks_count_1778 = status_filter(cossacks_1778, 'Козаки')
major_count_1778 = status_filter(major_1778, 'Офіцери PIA')
dukhovni_count_1778 = status_filter(dukhovni_1778, 'Духовенство')
pospolyti_count_1778 = status_filter(pospolyti_1778, 'Посполиті й бездвірні')
cossacks_count_1897 = status_filter(cossacks_1897, 'Козаки')
dukhovni_count_1897 = status_filter(dukhovni_1897, 'Духовенство')
nobels_count_1897 = status_filter(nobels_1897, 'Дворяни')
peasants_count_1897 = status_filter(peasants_1897, 'Селяни')
Для візуалізації такого набору даних я обрала sunburst chart, тому для цього потрібно змерджити дані у всіх листах за класом і категорією.
merged_cos_dukh_1778 = pd.merge(cossacks_count_1778, dukhovni_count_1778, on = ['Категорія', 'Клас'], how = 'left')
merged_cos_dukh_maj_1778 = pd.merge(merged_cos_dukh_1778, major_count_1778, on = ['Категорія', 'Клас'], how = 'left')
merged_1778 = merged_cos_dukh_maj_1778.merge(pospolyti_count_1778, on = ['Категорія', 'Клас'], how = 'left')
merged_1778
| Категорія | Клас | Козаки | Духовенство | Офіцери PIA | Посполиті й бездвірні | |
|---|---|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | 0 | 0 | 0 | 0 |
| 1 | NaN | Нежонаті, або неокресленого цивільного стану | 0 | 0 | 0 | 0 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | 0 | 0 | 0 | 0 |
| 3 | NaN | Інші кревні, які живуть разом | 0 | 0 | 0 | 0 |
| 4 | Нуклеарні | Шлюбі пари без дітей | 0 | 0 | 0 | 1 |
| 5 | NaN | Шлюбні пари з дітьми | 1 | 2 | 1 | 15 |
| 6 | NaN | Вдівці з дітьми | 0 | 0 | 0 | 0 |
| 7 | NaN | Вдови з дітьми | 0 | 0 | 0 | 1 |
| 8 | Розширені | Родини з висхідним розширенням | 0 | 0 | 0 | 1 |
| 9 | NaN | Родини з низхідним розширенням | 0 | 0 | 0 | 0 |
| 10 | NaN | Родини з бічним розширенням | 0 | 0 | 0 | 1 |
| 11 | NaN | Комбінація 4a-4c | 0 | 0 | 0 | 0 |
| 12 | Мультифокальні | Родини з висхідними другорядними ядрами | 0 | 0 | 0 | 1 |
| 13 | NaN | Родини з низхідними другорядними ядрами | 2 | 0 | 0 | 8 |
| 14 | NaN | Родини з бічними другорядними ядрами | 2 | 0 | 0 | 5 |
| 15 | NaN | Братські родини | 3 | 0 | 0 | 9 |
| 16 | NaN | Інші | 26 | 0 | 0 | 32 |
merged_cos_dukh_1897 = pd.merge(cossacks_count_1897, dukhovni_count_1897, on = ['Категорія', 'Клас'], how = 'left')
merged_cos_dukh_nob_1897 = pd.merge(merged_cos_dukh_1897, nobels_count_1897, on = ['Категорія', 'Клас'], how = 'left')
merged_1897 = merged_cos_dukh_nob_1897.merge(peasants_count_1897, on = ['Категорія', 'Клас'], how = 'left')
merged_1897
| Категорія | Клас | Козаки | Духовенство | Дворяни | Селяни | |
|---|---|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | 1 | 0 | 0 | 2 |
| 1 | NaN | Нежонаті, або неокресленого цивільного стану | 0 | 0 | 1 | 1 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | 0 | 0 | 0 | 0 |
| 3 | NaN | Інші кревні, які живуть разом | 1 | 0 | 0 | 0 |
| 4 | Нуклеарні | Шлюбі пари без дітей | 4 | 0 | 0 | 7 |
| 5 | NaN | Шлюбні пари з дітьми | 54 | 1 | 0 | 32 |
| 6 | NaN | Вдівці з дітьми | 1 | 0 | 0 | 2 |
| 7 | NaN | Вдови з дітьми | 4 | 0 | 0 | 8 |
| 8 | Розширені | Родини з висхідним розширенням | 16 | 1 | 0 | 13 |
| 9 | NaN | Родини з низхідним розширенням | 3 | 0 | 0 | 1 |
| 10 | NaN | Родини з бічним розширенням | 3 | 0 | 0 | 11 |
| 11 | NaN | Комбінація 4a-4c | 2 | 0 | 0 | 2 |
| 12 | Мультифокальні | Родини з висхідними другорядними ядрами | 6 | 0 | 0 | 2 |
| 13 | NaN | Родини з низхідними другорядними ядрами | 36 | 0 | 1 | 24 |
| 14 | NaN | Родини з бічними другорядними ядрами | 4 | 0 | 0 | 2 |
| 15 | NaN | Братські родини | 7 | 0 | 0 | 2 |
| 16 | NaN | Інші | 4 | 0 | 0 | 1 |
Застосовано pd.ffill(), щоб у кожному рядку було значення категорії
merged_1778['Категорія'] = merged_1778['Категорія'].ffill()
merged_1778
| Категорія | Клас | Козаки | Духовенство | Офіцери PIA | Посполиті й бездвірні | |
|---|---|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | 0 | 0 | 0 | 0 |
| 1 | Самотні особи | Нежонаті, або неокресленого цивільного стану | 0 | 0 | 0 | 0 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | 0 | 0 | 0 | 0 |
| 3 | Безструктурні | Інші кревні, які живуть разом | 0 | 0 | 0 | 0 |
| 4 | Нуклеарні | Шлюбі пари без дітей | 0 | 0 | 0 | 1 |
| 5 | Нуклеарні | Шлюбні пари з дітьми | 1 | 2 | 1 | 15 |
| 6 | Нуклеарні | Вдівці з дітьми | 0 | 0 | 0 | 0 |
| 7 | Нуклеарні | Вдови з дітьми | 0 | 0 | 0 | 1 |
| 8 | Розширені | Родини з висхідним розширенням | 0 | 0 | 0 | 1 |
| 9 | Розширені | Родини з низхідним розширенням | 0 | 0 | 0 | 0 |
| 10 | Розширені | Родини з бічним розширенням | 0 | 0 | 0 | 1 |
| 11 | Розширені | Комбінація 4a-4c | 0 | 0 | 0 | 0 |
| 12 | Мультифокальні | Родини з висхідними другорядними ядрами | 0 | 0 | 0 | 1 |
| 13 | Мультифокальні | Родини з низхідними другорядними ядрами | 2 | 0 | 0 | 8 |
| 14 | Мультифокальні | Родини з бічними другорядними ядрами | 2 | 0 | 0 | 5 |
| 15 | Мультифокальні | Братські родини | 3 | 0 | 0 | 9 |
| 16 | Мультифокальні | Інші | 26 | 0 | 0 | 32 |
merged_1897['Категорія'] = merged_1897['Категорія'].ffill()
merged_1897
| Категорія | Клас | Козаки | Духовенство | Дворяни | Селяни | |
|---|---|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | 1 | 0 | 0 | 2 |
| 1 | Самотні особи | Нежонаті, або неокресленого цивільного стану | 0 | 0 | 1 | 1 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | 0 | 0 | 0 | 0 |
| 3 | Безструктурні | Інші кревні, які живуть разом | 1 | 0 | 0 | 0 |
| 4 | Нуклеарні | Шлюбі пари без дітей | 4 | 0 | 0 | 7 |
| 5 | Нуклеарні | Шлюбні пари з дітьми | 54 | 1 | 0 | 32 |
| 6 | Нуклеарні | Вдівці з дітьми | 1 | 0 | 0 | 2 |
| 7 | Нуклеарні | Вдови з дітьми | 4 | 0 | 0 | 8 |
| 8 | Розширені | Родини з висхідним розширенням | 16 | 1 | 0 | 13 |
| 9 | Розширені | Родини з низхідним розширенням | 3 | 0 | 0 | 1 |
| 10 | Розширені | Родини з бічним розширенням | 3 | 0 | 0 | 11 |
| 11 | Розширені | Комбінація 4a-4c | 2 | 0 | 0 | 2 |
| 12 | Мультифокальні | Родини з висхідними другорядними ядрами | 6 | 0 | 0 | 2 |
| 13 | Мультифокальні | Родини з низхідними другорядними ядрами | 36 | 0 | 1 | 24 |
| 14 | Мультифокальні | Родини з бічними другорядними ядрами | 4 | 0 | 0 | 2 |
| 15 | Мультифокальні | Братські родини | 7 | 0 | 0 | 2 |
| 16 | Мультифокальні | Інші | 4 | 0 | 0 | 1 |
Переведено у довгий формат для збільшення кількості "корінців" під кожною категорією
melt_1778 = merged_1778.melt(id_vars=['Категорія', 'Клас'],value_vars=['Козаки', 'Духовенство', 'Офіцери PIA', 'Посполиті й бездвірні'],var_name='group',value_name='count')
melt_1778
| Категорія | Клас | group | count | |
|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | Козаки | 0 |
| 1 | Самотні особи | Нежонаті, або неокресленого цивільного стану | Козаки | 0 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | Козаки | 0 |
| 3 | Безструктурні | Інші кревні, які живуть разом | Козаки | 0 |
| 4 | Нуклеарні | Шлюбі пари без дітей | Козаки | 0 |
| ... | ... | ... | ... | ... |
| 63 | Мультифокальні | Родини з висхідними другорядними ядрами | Посполиті й бездвірні | 1 |
| 64 | Мультифокальні | Родини з низхідними другорядними ядрами | Посполиті й бездвірні | 8 |
| 65 | Мультифокальні | Родини з бічними другорядними ядрами | Посполиті й бездвірні | 5 |
| 66 | Мультифокальні | Братські родини | Посполиті й бездвірні | 9 |
| 67 | Мультифокальні | Інші | Посполиті й бездвірні | 32 |
68 rows × 4 columns
melt_1897 = merged_1897.melt(id_vars=['Категорія', 'Клас'],value_vars=['Козаки', 'Духовенство', 'Дворяни', 'Селяни'],var_name='group',value_name='count')
melt_1897
| Категорія | Клас | group | count | |
|---|---|---|---|---|
| 0 | Самотні особи | Вдови і вдівці | Козаки | 1 |
| 1 | Самотні особи | Нежонаті, або неокресленого цивільного стану | Козаки | 0 |
| 2 | Безструктурні | Нежонаті брати і сестри, які живуть разом | Козаки | 0 |
| 3 | Безструктурні | Інші кревні, які живуть разом | Козаки | 1 |
| 4 | Нуклеарні | Шлюбі пари без дітей | Козаки | 4 |
| ... | ... | ... | ... | ... |
| 63 | Мультифокальні | Родини з висхідними другорядними ядрами | Селяни | 2 |
| 64 | Мультифокальні | Родини з низхідними другорядними ядрами | Селяни | 24 |
| 65 | Мультифокальні | Родини з бічними другорядними ядрами | Селяни | 2 |
| 66 | Мультифокальні | Братські родини | Селяни | 2 |
| 67 | Мультифокальні | Інші | Селяни | 1 |
68 rows × 4 columns
Для побудови цього типу графіка найзручніше використовувати бібліотеку plotly.
fig = px.sunburst(melt_1778, path=['group', 'Категорія', 'Клас'], values='count', title= 'Соціальна структура сімей (1778)',width=700,height=700)
fig.update_layout(font_family="Comic Sans MS", title_font_size=25, title_x=0.5)
fig.show()
fig = px.sunburst(melt_1897, path=['group', 'Категорія', 'Клас'], values='count', title= 'Соціальна структура сімей (1897)',width=700,height=700)
fig.update_layout(font_family="Comic Sans MS", title_font_size=25, title_x=0.5)
fig.show()
З огляду на результати обох візуалізацій, можна зробити висновок, що кількість козаків дещо зросла, а саме козацтво ліквідували ще століття до того. Однак попри це, козаки залишалися ще окремою групою, відмінною від селян і дворян. Вони були зобовязані відбувати службу і мали свої привілеї. Отже, і з огляду на це родини частіше мали дітей.
Співвідношення соціального статусу до сімейного¶
Оскільки в переписі 1778 року немає колонки, яка стосується сімейного статусу, її було створено на базі колонки про статус у сім'ї. Для цього сформована функція, яка перебиратиме значення до 3 категорій: вдовець/а, неодружений/а, одружений/а
def fam_status_definer(status):
if isinstance(status, str) and any(term in status for term in ['вдов','вдова','удова']):
return 'вдовець/a'
elif isinstance(status, str) and any(term in status for term in ["племянник",'дочь','доч','сын','племянница']):
return 'неодружений/а'
elif isinstance(status, str) and any(term in status for term in ["муж",'жена','невестка','господар', 'брат', 'дядя', 'зять']):
return 'одружений/а'
else:
return None
Для іншого датасету, в якому є сімейний статус, значення були перекладені на відповідні
pop_1897['Семейный статус'].replace(['vidov', 'unmarried', 'married'], ['вдовець/a', 'неодружений/а', 'одружений/а'], inplace = True)
pop_1897
/var/folders/k1/s2xy8pbx3h991jnqmnthbtzh0000gn/T/ipykernel_57806/2445264546.py:1: FutureWarning:
A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.
The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.
For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.
| Кто заполнял базу | ID строки в базе | List ID | Link | ID Домохозяйствао | ID жилец | ФИО | gender | Глава хозяйства и глава семьи | age | ... | Отметка об отсуствии | Вероисповедание | Родной язык | Умеет ли читать | Обучение | Профессия главное | Профессия вспомогательное | Положение по воинской повинности | Примітки | age_group | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Podhorna | 1.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 1.0 | Krasovskij Pantelejmon Ivanovich | m | husband | 32 | ... | NaN | orthodox | ukr | 1.0 | rural school | farmer | NaN | Nizhnij chin zapasu | NaN | 30-34 |
| 1 | Podhorna | 2.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 2.0 | Krasovskaya Stefanida Artemieva | f | wife | 28 | ... | NaN | orthodox | ukr | 0.0 | NaN | farmer with husband | NaN | NaN | NaN | 25-29 |
| 2 | Podhorna | 3.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 3.0 | Krasovskaya Anna Pantelejmonova | f | daughter | 5 | ... | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN | 5-9 |
| 3 | Podhorna | 4.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 4.0 | Krasovskij Stefan Pantelejmonov | m | son | 1 | ... | NaN | orthodox | ukrm | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 |
| 4 | Podhorna | 5.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 5.0 | Krasovskij Ivan Kondratov | m | father | 70 | ... | NaN | orthodox | ukr | 0.0 | NaN | with son | NaN | NaN | Slep na oba hlaza 10 let nazad | 70-74 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1547 | Podhorna | 1548.0 | F.132.Op.1.Spr.1343. Арк.550-551 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 261.0 | 6.0 | Gricunov Mikhail Sergeev | m | son | 3 | ... | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 |
| 1548 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1549 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1550 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1551 | * - В оригінальному джерелі ячейка "мова" була... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
1552 rows × 26 columns
Для обох датасетів значення соціальної групи є зведеними до ширших груп і перекладеними
pop_1778['fam_status'] = pop_1778['family_status_rus'].apply(fam_status_definer)
pop_1778['status'] = pop_1778['status'].replace({'бездворные': 'бездвірні','военные': 'козаки','дворовые': 'селяни','духовные': 'духовні','посполитые': 'посполиті'})
pop_1778
| Unnamed: 0 | Unnamed: 1 | family_num | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | men | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 12 | Unnamed: 13 | status | age | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | gender | age_group | fam_status | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None |
| 1 | Аркуш | NaN | NaN | NaN | Число людей наскрізне | NaN | Число людей джерело | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None |
| 2 | NaN | ID наскрізна | ID домогосподарство | Двори джерело | Чоловіки | Жінки | Чоловіки | Жінки | Імʼя | По-батькові | ... | Категорія | Клас | Соціальний статус | Вік | Був на сповіді | Не був | Не був за малолітством | NaN | None | None |
| 3 | 445 | 1 | 1 | 1 | 1 | NaN | 1 | NaN | Федор | Кондратьев | ... | nuclear | 3b | духовні | 44 | х | NaN | NaN | m | 40-44 | одружений/а |
| 4 | NaN | 2 | NaN | NaN | NaN | 1 | NaN | 1 | Варвара | Симева | ... | NaN | NaN | духовні | 35 | х | NaN | NaN | f | 35-39 | одружений/а |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1595 | NaN | 1593 | 104 | 12 | 824 | NaN | 236 | NaN | Леонтий | Афанасиев | ... | nuclear | 3a | бездвірні | 25 | х | NaN | NaN | m | 25-29 | одружений/а |
| 1596 | NaN | 1594 | NaN | NaN | NaN | 770 | NaN | 222 | Мотрона | Михайлова | ... | NaN | NaN | бездвірні | 22 | х | NaN | NaN | f | 20-24 | одружений/а |
| 1597 | NaN | 1595 | 105 | 13 | 825 | NaN | 237 | NaN | Герасим | Фомик | ... | nuclear | 3b | бездвірні | 43 | х | NaN | NaN | m | 40-44 | одружений/а |
| 1598 | NaN | 1596 | NaN | NaN | NaN | 771 | NaN | 223 | Агафия | Максимова | ... | NaN | NaN | бездвірні | 42 | х | NaN | NaN | f | 40-44 | одружений/а |
| 1599 | NaN | 1597 | NaN | NaN | 826 | NaN | 238 | NaN | Лукьян | NaN | ... | NaN | NaN | бездвірні | 14 | х | NaN | NaN | m | 10-14 | None |
1600 rows × 22 columns
pop_1897['Сословие, состояние или звание'] = pop_1897['Сословие, состояние или звание'].replace({'citizen': 'містяни','cossack': 'козаки','dukhovnogo': 'духовні', 'nobles': 'дворяни','peasant-owner': 'селяни','dvorovyj': 'селяни','state peasant': 'селяни','imenuyushchijsya dvoryanin': 'дворяни'})
pop_1897
| Кто заполнял базу | ID строки в базе | List ID | Link | ID Домохозяйствао | ID жилец | ФИО | gender | Глава хозяйства и глава семьи | age | ... | Отметка об отсуствии | Вероисповедание | Родной язык | Умеет ли читать | Обучение | Профессия главное | Профессия вспомогательное | Положение по воинской повинности | Примітки | age_group | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Podhorna | 1.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 1.0 | Krasovskij Pantelejmon Ivanovich | m | husband | 32 | ... | NaN | orthodox | ukr | 1.0 | rural school | farmer | NaN | Nizhnij chin zapasu | NaN | 30-34 |
| 1 | Podhorna | 2.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 2.0 | Krasovskaya Stefanida Artemieva | f | wife | 28 | ... | NaN | orthodox | ukr | 0.0 | NaN | farmer with husband | NaN | NaN | NaN | 25-29 |
| 2 | Podhorna | 3.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 3.0 | Krasovskaya Anna Pantelejmonova | f | daughter | 5 | ... | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN | 5-9 |
| 3 | Podhorna | 4.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 4.0 | Krasovskij Stefan Pantelejmonov | m | son | 1 | ... | NaN | orthodox | ukrm | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 |
| 4 | Podhorna | 5.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 5.0 | Krasovskij Ivan Kondratov | m | father | 70 | ... | NaN | orthodox | ukr | 0.0 | NaN | with son | NaN | NaN | Slep na oba hlaza 10 let nazad | 70-74 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1547 | Podhorna | 1548.0 | F.132.Op.1.Spr.1343. Арк.550-551 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 261.0 | 6.0 | Gricunov Mikhail Sergeev | m | son | 3 | ... | NaN | orthodox | ukr | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 |
| 1548 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1549 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1550 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
| 1551 | * - В оригінальному джерелі ячейка "мова" була... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None |
1552 rows × 26 columns
Після цього значення погруповані за кількістю пари категорій
grouped_1778 = pop_1778.groupby(['fam_status', 'status']).size().reset_index(name='count')
grouped_1778.sort_values(by=['count'], ascending=False, inplace=True)
grouped_1778
| fam_status | status | count | |
|---|---|---|---|
| 6 | неодружений/а | козаки | 437 |
| 7 | неодружений/а | посполиті | 382 |
| 12 | одружений/а | посполиті | 292 |
| 11 | одружений/а | козаки | 256 |
| 4 | неодружений/а | бездвірні | 44 |
| 9 | одружений/а | бездвірні | 34 |
| 1 | вдовець/a | козаки | 27 |
| 2 | вдовець/a | посполиті | 22 |
| 8 | неодружений/а | селяни | 22 |
| 13 | одружений/а | селяни | 13 |
| 5 | неодружений/а | духовні | 7 |
| 0 | вдовець/a | бездвірні | 4 |
| 10 | одружений/а | духовні | 3 |
| 3 | вдовець/a | селяни | 2 |
grouped_1897 = pop_1897.groupby(['Семейный статус', 'Сословие, состояние или звание']).size().reset_index(name='count')
grouped_1897.sort_values('count', ascending=False, inplace=True)
grouped_1897['Сословие, состояние или звание'].unique()
grouped_1897
| Семейный статус | Сословие, состояние или звание | count | |
|---|---|---|---|
| 5 | неодружений/а | козаки | 448 |
| 10 | одружений/а | козаки | 365 |
| 7 | неодружений/а | селяни | 354 |
| 12 | одружений/а | селяни | 246 |
| 1 | вдовець/a | козаки | 57 |
| 2 | вдовець/a | селяни | 43 |
| 4 | неодружений/а | духовні | 8 |
| 3 | неодружений/а | дворяни | 6 |
| 8 | одружений/а | дворяни | 5 |
| 6 | неодружений/а | містяни | 4 |
| 9 | одружений/а | духовні | 4 |
| 11 | одружений/а | містяни | 3 |
| 0 | вдовець/a | духовні | 1 |
Для побудови цієї візуалізації я використала бібліотеку Altair і зобразила у формі heat map. При наведенні курсора на значення показує точну кількість осіб певної категорії
status_heatmap_1778 = alt.Chart(grouped_1778).mark_rect().encode(x=alt.X('fam_status:O', title='Сімейний статус'), y=alt.Y('status:O', title='Соціальна група'), color='count:Q', tooltip=['count']).properties(title = '1778', height = 200, width = 100).interactive()
status_heatmap_1897 = alt.Chart(grouped_1897).mark_rect().encode(x=alt.X('Семейный статус:O', title='Сімейний статус'), y=alt.Y('Сословие, состояние или звание:O', title='Соціальна група'), color='count:Q', tooltip=['count']).properties(title = '1897', height = 200, width = 100).interactive()
alt.concat(status_heatmap_1778,status_heatmap_1897).properties(title = 'Співвідношення соціальної групи до сімейного статусу').resolve_scale(y='shared')
Результат показує, що у 1778 році найпомітнішими групами були козаки та посполиті, що складали переважну більшість одружених осіб. У 1897 році це зберігається, проте змінюється характер розподілу: значно зростає кількість селян, які представлені серед одружених. З'являються нові соціальні групи, такі як містяни і дворяни, що вказує на зміну у соціальній структурі імперії протягом століття.
Національна структура і родини¶
Порівняння національної частки населення за походженням прізвищ¶
Проаналізувавши соціальну структуру родин села Дунаєць, я вирішила розширити дослідження та звернути увагу на зміну національної структури села. Це питання є актуальним, адже ліквідація козацького стану, процеси русифікації й утиску українців, а також початок індустріалізації дали дали шлях до переселення російської людності на українські території. Ось, яку інформацію мені вдалося знайти на вікіпедії
У світлі перепису 1897 (даних про кількість росіян в Україні до того часу нема) на українській суцільній етнографічній території жило 3,8 млн росіян на 27,8 млн всього населення, тобто вони становили 11,7 %
У зв'язку з відсутністю прямих вказівок на етнічну приналежність, я вирішила зробити орієнтовний аналіз походження прізвищ за суфіксами та іншими правилами, що вказують на його походження. Такий підхід є ще виправданим до XIX століття, оскільки прізвища у селян почали масово з'являтися у XVII ст., і протягом наступних двох століть не зазнавало великої асиміляції, зберігаючи зв'язок з національною ідентичністю.
Оскільки дані в переписах населення відрізняються, перше, що потрібно провести, це зведення прізвищ до "спільного знаменника". Логічно найзручнішим буде переклад прізвищ на українську мову. З даними перепису 1778 року буде простіше, оскільки потрібно замінити лише деякі букви (напр. И на початку слова на І) або суфікси (-ск- на -ськ-, -ин на -ін, але не вводити переклад и на і напряму, бо, наприклад, прізвище Лукашевич, Василенко не будуть перекладені як Лукашевіч, Васіленко)
pop_1778['surname'] = pop_1778['rus_surname'].replace(['ец', 'иш', 'ой', 'ье', 'ск', 'ие', 'И', 'ы', 'еенко', 'ин', 'ина'], ['ець', 'іш', 'ий', 'є', 'ськ', 'іє', 'І', 'и', 'ієнко', 'ін', 'іна'], regex = True)
pop_1778
| Unnamed: 0 | Unnamed: 1 | family_num | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | men | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 13 | status | age | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | gender | age_group | fam_status | surname | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None | NaN |
| 1 | Аркуш | NaN | NaN | NaN | Число людей наскрізне | NaN | Число людей джерело | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None | NaN |
| 2 | NaN | ID наскрізна | ID домогосподарство | Двори джерело | Чоловіки | Жінки | Чоловіки | Жінки | Імʼя | По-батькові | ... | Клас | Соціальний статус | Вік | Був на сповіді | Не був | Не був за малолітством | NaN | None | None | Прізвище |
| 3 | 445 | 1 | 1 | 1 | 1 | NaN | 1 | NaN | Федор | Кондратьев | ... | 3b | духовні | 44 | х | NaN | NaN | m | 40-44 | одружений/а | Лукашевич |
| 4 | NaN | 2 | NaN | NaN | NaN | 1 | NaN | 1 | Варвара | Симева | ... | NaN | духовні | 35 | х | NaN | NaN | f | 35-39 | одружений/а | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1595 | NaN | 1593 | 104 | 12 | 824 | NaN | 236 | NaN | Леонтий | Афанасиев | ... | 3a | бездвірні | 25 | х | NaN | NaN | m | 25-29 | одружений/а | NaN |
| 1596 | NaN | 1594 | NaN | NaN | NaN | 770 | NaN | 222 | Мотрона | Михайлова | ... | NaN | бездвірні | 22 | х | NaN | NaN | f | 20-24 | одружений/а | NaN |
| 1597 | NaN | 1595 | 105 | 13 | 825 | NaN | 237 | NaN | Герасим | Фомик | ... | 3b | бездвірні | 43 | х | NaN | NaN | m | 40-44 | одружений/а | Мерник |
| 1598 | NaN | 1596 | NaN | NaN | NaN | 771 | NaN | 223 | Агафия | Максимова | ... | NaN | бездвірні | 42 | х | NaN | NaN | f | 40-44 | одружений/а | NaN |
| 1599 | NaN | 1597 | NaN | NaN | 826 | NaN | 238 | NaN | Лукьян | NaN | ... | NaN | бездвірні | 14 | х | NaN | NaN | m | 10-14 | None | NaN |
1600 rows × 23 columns
Для кожної особи надано значення прізвища
pop_1778['surname'] = pop_1778['surname'].ffill()
pop_1778
| Unnamed: 0 | Unnamed: 1 | family_num | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 | men | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 13 | status | age | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | gender | age_group | fam_status | surname | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None | NaN |
| 1 | Аркуш | NaN | NaN | NaN | Число людей наскрізне | NaN | Число людей джерело | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | None | None | NaN |
| 2 | NaN | ID наскрізна | ID домогосподарство | Двори джерело | Чоловіки | Жінки | Чоловіки | Жінки | Імʼя | По-батькові | ... | Клас | Соціальний статус | Вік | Був на сповіді | Не був | Не був за малолітством | NaN | None | None | Прізвище |
| 3 | 445 | 1 | 1 | 1 | 1 | NaN | 1 | NaN | Федор | Кондратьев | ... | 3b | духовні | 44 | х | NaN | NaN | m | 40-44 | одружений/а | Лукашевич |
| 4 | NaN | 2 | NaN | NaN | NaN | 1 | NaN | 1 | Варвара | Симева | ... | NaN | духовні | 35 | х | NaN | NaN | f | 35-39 | одружений/а | Лукашевич |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1595 | NaN | 1593 | 104 | 12 | 824 | NaN | 236 | NaN | Леонтий | Афанасиев | ... | 3a | бездвірні | 25 | х | NaN | NaN | m | 25-29 | одружений/а | Кислая |
| 1596 | NaN | 1594 | NaN | NaN | NaN | 770 | NaN | 222 | Мотрона | Михайлова | ... | NaN | бездвірні | 22 | х | NaN | NaN | f | 20-24 | одружений/а | Кислая |
| 1597 | NaN | 1595 | 105 | 13 | 825 | NaN | 237 | NaN | Герасим | Фомик | ... | 3b | бездвірні | 43 | х | NaN | NaN | m | 40-44 | одружений/а | Мерник |
| 1598 | NaN | 1596 | NaN | NaN | NaN | 771 | NaN | 223 | Агафия | Максимова | ... | NaN | бездвірні | 42 | х | NaN | NaN | f | 40-44 | одружений/а | Мерник |
| 1599 | NaN | 1597 | NaN | NaN | 826 | NaN | 238 | NaN | Лукьян | NaN | ... | NaN | бездвірні | 14 | х | NaN | NaN | m | 10-14 | None | Мерник |
1600 rows × 23 columns
Посилаючись на те, що важливим є саме переклад прізвища, колонку "ФИО" в переписі 1897 року було поділено на колонки з прізвищем, ім'ям і побатькові.
pop_1897['surname_og'] = pop_1897['ФИО'].str.split(expand = True)[0].str.capitalize()
pop_1897['name'] = pop_1897['ФИО'].str.split(expand = True)[1].str.capitalize()
pop_1897['middle_name'] = pop_1897['ФИО'].str.split(expand = True)[2].str.capitalize()
pop_1897
| Кто заполнял базу | ID строки в базе | List ID | Link | ID Домохозяйствао | ID жилец | ФИО | gender | Глава хозяйства и глава семьи | age | ... | Умеет ли читать | Обучение | Профессия главное | Профессия вспомогательное | Положение по воинской повинности | Примітки | age_group | surname_og | name | middle_name | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Podhorna | 1.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 1.0 | Krasovskij Pantelejmon Ivanovich | m | husband | 32 | ... | 1.0 | rural school | farmer | NaN | Nizhnij chin zapasu | NaN | 30-34 | Krasovskij | Pantelejmon | Ivanovich |
| 1 | Podhorna | 2.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 2.0 | Krasovskaya Stefanida Artemieva | f | wife | 28 | ... | 0.0 | NaN | farmer with husband | NaN | NaN | NaN | 25-29 | Krasovskaya | Stefanida | Artemieva |
| 2 | Podhorna | 3.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 3.0 | Krasovskaya Anna Pantelejmonova | f | daughter | 5 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 5-9 | Krasovskaya | Anna | Pantelejmonova |
| 3 | Podhorna | 4.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 4.0 | Krasovskij Stefan Pantelejmonov | m | son | 1 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 | Krasovskij | Stefan | Pantelejmonov |
| 4 | Podhorna | 5.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 5.0 | Krasovskij Ivan Kondratov | m | father | 70 | ... | 0.0 | NaN | with son | NaN | NaN | Slep na oba hlaza 10 let nazad | 70-74 | Krasovskij | Ivan | Kondratov |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1547 | Podhorna | 1548.0 | F.132.Op.1.Spr.1343. Арк.550-551 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 261.0 | 6.0 | Gricunov Mikhail Sergeev | m | son | 3 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 | Gricunov | Mikhail | Sergeev |
| 1548 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1549 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1550 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1551 | * - В оригінальному джерелі ячейка "мова" була... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
1552 rows × 29 columns
Для перекладу прізвищ з перепису 1897 року використано pd.translate(str.maketrans()) і pd.replace(). Другий для деяких суфіксів і літер, які не мають прямих відповідників англійською, а після цього перший, щоб перекласти те, що залишилось
mytable = str.maketrans({'w': 'в', 'e': 'е', 'r': 'р', 't': 'т', 'y': 'и','u': 'у', 'i': 'и', 'o': 'о', 'p': 'п', 'a': 'а', 's': 'с', 'd': 'д', 'f': 'ф', 'g': 'г', 'h': 'г', 'j': 'й', 'k': 'к', 'l': 'л', 'z': 'з', 'c': 'с', 'v': 'в','b': 'б', 'n': 'н', 'm': 'м', "'": 'ь'})
pop_1897['two_let'] = pop_1897['surname_og'].replace(['ina', 'in', 'eenko', 'aya', 'yj', 'ya', 'esh', 'shch', 'ch', 'yi', 'ye', 'yu', 'ts', 'sh', 'zh', 'kh', 'ai', 'sk', 'ij', 'ie', 'Ya', 'Ye', 'Yi', 'Yu', 'I', 'E', 'C'], ['іна', 'ін', 'ієнко', 'а', 'ий', 'я', 'іш', 'щ', 'ч', 'ї', 'є', 'ю', 'ц', 'ш', 'ж', 'х', 'аї', 'ськ', "ий", 'іє', 'Я', 'Є', 'Ї', 'Ю', 'І', "Є", 'Ц'], regex = True)
pop_1897['surname'] = pop_1897['two_let'].str.lower().str.translate(mytable).str.capitalize()
pop_1897 = pop_1897.drop(columns = ['surname_og', 'two_let'])
pop_1897
| Кто заполнял базу | ID строки в базе | List ID | Link | ID Домохозяйствао | ID жилец | ФИО | gender | Глава хозяйства и глава семьи | age | ... | Умеет ли читать | Обучение | Профессия главное | Профессия вспомогательное | Положение по воинской повинности | Примітки | age_group | name | middle_name | surname | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Podhorna | 1.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 1.0 | Krasovskij Pantelejmon Ivanovich | m | husband | 32 | ... | 1.0 | rural school | farmer | NaN | Nizhnij chin zapasu | NaN | 30-34 | Pantelejmon | Ivanovich | Красовський |
| 1 | Podhorna | 2.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 2.0 | Krasovskaya Stefanida Artemieva | f | wife | 28 | ... | 0.0 | NaN | farmer with husband | NaN | NaN | NaN | 25-29 | Stefanida | Artemieva | Красовська |
| 2 | Podhorna | 3.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 3.0 | Krasovskaya Anna Pantelejmonova | f | daughter | 5 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 5-9 | Anna | Pantelejmonova | Красовська |
| 3 | Podhorna | 4.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 4.0 | Krasovskij Stefan Pantelejmonov | m | son | 1 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 | Stefan | Pantelejmonov | Красовський |
| 4 | Podhorna | 5.0 | F.132.Op.1.Spr.1343. Арк.1-2 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 1.0 | 5.0 | Krasovskij Ivan Kondratov | m | father | 70 | ... | 0.0 | NaN | with son | NaN | NaN | Slep na oba hlaza 10 let nazad | 70-74 | Ivan | Kondratov | Красовський |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1547 | Podhorna | 1548.0 | F.132.Op.1.Spr.1343. Арк.550-551 | https://www.familysearch.org/ark:/61903/3:1:3Q... | 261.0 | 6.0 | Gricunov Mikhail Sergeev | m | son | 3 | ... | 0.0 | NaN | with father | NaN | NaN | NaN | 0-4 | Mikhail | Sergeev | Грисунов |
| 1548 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1549 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1550 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
| 1551 | * - В оригінальному джерелі ячейка "мова" була... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN |
1552 rows × 29 columns
pop_1897['surname'].unique()
array(['Красовський', 'Красовська', 'Скоропад', 'Скоропадова',
'Беловська', 'Беловський', 'Старченко', 'Бобровийський',
'Бобровийська', 'Лукаш', 'Лукашова', 'Михнюк', 'Бортникова',
'Дручок', 'Дручкова', 'Знобей', 'Знобеева', 'Двореский',
'Мартіненко', 'Сачков', 'Сачкова', 'Бортник', 'Малафієнко',
'Петрик', 'Петрикова', 'Печений', 'Печена', 'Соломяний', 'Рудич',
'Рибалка', 'Рибалкіна', 'Гаевий', 'Гаева', 'Позняк', 'Познякова',
'Давиденко', 'Сгульга', 'Сгульгіна', 'Гаврик', 'Гаврикова',
'Сапожников', 'Сапожникова', 'Контрибус', 'Контрибусева',
'Созоненкова', 'Ясуков', 'Ясукова', 'Комаров', 'Комарова',
'Ляшенко', 'Оничко', 'Манжос', 'Манжосова', 'Пташник',
'Пташникова', 'Корсун', 'Корсунова', 'Юша', 'Юшіна', 'Багнюков',
'Багнюкова', 'Сгчербак', 'Кулибакіна', 'Кулибака', 'Гайдукова',
'Соломений', 'Мищенко', 'Гайдук', 'Воробей', 'Воробйова',
'Сковорода', 'Сковородіна', 'Ядутін', 'Ядутіна', 'Горкун',
'Горкунова', 'Івансов', 'Івансова', 'Козел', 'Козлова', 'Цигикал',
'Цигикалова', 'Козлов', 'Василий', 'Мукорез', 'Мукорезова',
'Костюченкова', 'Рожен', 'Рожнова', 'Тищенко', 'Новобранний',
'Красовиский', 'Бирінова', 'Бирін', 'Бабенкова', 'Соломяна',
'Ігнатенко', 'Дьяченко', 'Лобас', 'Лобасова', 'Воробьева', 'Очкал',
'Очкалова', 'Мехедкова', 'Мехедок', 'Березний', 'Березна',
'Гуреев', 'Гуреева', 'Юшін', 'Сгумейко', 'Онопрієнко', 'Бабич',
'Бабичева', 'Противен', 'Колоша', 'Колошіна', 'Моськовченко',
'Кузнесов', 'Кузнесова', 'Малафієнкова', 'Вороей', 'Мороз',
'Морозова', 'Довгополий', 'Довгопола', 'Николай', 'Овсієнко',
'Мигаїл', 'Іван', 'Божок', 'Божкова', 'Белоусова', 'Оноденко',
'Купіна', 'Фалева', 'Макаренко', 'Кушнеров', 'Кушнерова',
'Овчаренко', nan, 'Овсієнкова', 'Науменко', 'Рой', 'Роева',
'Таратінова', 'Науменкова', 'Понурко', 'Половінка', 'Прилуска',
'Петр', 'Тищенкова', 'Опанасенко', 'Кириченко', 'Громакова',
'Дятел', 'Середа', 'Закройсева', 'Кулішова', 'Куліш',
'Лавренченко', 'Кульбакіна', 'Малофієнко', 'Вегеза', 'Оксененко',
'Мигаленко', 'Лобасенко', 'Єременко', 'Приданова', 'Згуравлева',
'Цгеркасова', 'Бойко', 'Савиский', 'Сависка', 'Старченкова',
'Белявський', 'Белявська', 'Таратіна', 'Таратін', 'Павловський',
'Грисунов', 'Грисунова'], dtype=object)
Далі йде класифікація. У ній я створила 2 набори суфіксів різних походжень і також список професій, в честь яких існує багато українських прізвищ
ukr_suffixes_re = r'ук$|юк$|ів$|ець$|ик$|ко$|ар$|яр$|(?<!ов)ський$|(?<!ов)ська$|ень$|ич$|йч$|ун$|яний$|яна$|ений$|ена$|ок$|аевий$|аева$|иха$|ака$|ак$|аль$|ач$'
some_ukr_job_surnames = ['Коваль', 'Ткач', 'Стельмах', "Кожум'яка", 'Драч', 'Лукаш', 'Скоропад', 'Куліш', 'Середа']
rus_suffixes_re = r'ов$|ев$|ін$|ова$|ева$|іна$|єв$|єва$|овський$|овська$|овській$|ськой$|ськая$|ский$|ин$|ина$|ая$'
Функції ukr_mask(df) та rus_mask(df), де df -- відповідний датафрейм, створені для фільтрації датасетів відповідно до суфіксів і списку наведених вище
def ukr_mask(df):
mask = df['surname'].str.contains(ukr_suffixes_re, regex = True, na = False) | (df['surname'].isin(some_ukr_job_surnames))
return mask
def rus_mask(df):
mask = df['surname'].str.contains(rus_suffixes_re, regex = True, na = False)
return mask
Було введено ще інші прізвища, в які або не можна чітко класифікувати й вони потребують окремого аналізу, або мають помилки в написанні
def surnames_classification(df):
ukr_surnames = df[ukr_mask(df)]
rus_surnames = df[rus_mask(df)]
other_surnames = df[~(rus_mask(df) | ukr_mask(df))]
return (ukr_surnames, rus_surnames, other_surnames)
ukr_surnames_1778 = surnames_classification(pop_1778)[0]
rus_surnames_1778 = surnames_classification(pop_1778)[1]
other_surnames_1778 = surnames_classification(pop_1778)[2]
ukr_surnames_1897 = surnames_classification(pop_1897)[0]
rus_surnames_1897 = surnames_classification(pop_1897)[1]
other_surnames_1897 = surnames_classification(pop_1897)[2]
Для візуалізації цього розподілу я побудувала пайчарт, виористовуючи бібліотеку matplotlib
origins = ['Українські', 'Російські','Інші']
fig, ax = plt.subplots(1,2, sharey = True)
fig.suptitle("Походження прізвищ")
colors = ['gold', 'salmon', 'mediumspringgreen']
ax[0].pie([len(ukr_surnames_1778), len(rus_surnames_1778), len(other_surnames_1778)], labels = origins, autopct='%1.1f%%', startangle=140, colors = colors)
ax[0].set_title('1778')
ax[1].pie([len(ukr_surnames_1897), len(rus_surnames_1897), len(other_surnames_1897)], labels = origins, autopct='%1.1f%%', startangle=140, colors = colors)
ax[1].set_title('1897')
plt.show()
Більшість прізвищ все-таки класифікувались, що дало приблизно однакову частку прізвищ "іншого" походження. Результати візуалізації показують, що частка росіян істотно збільшилась на 20%, охопивши таку ж частку українців, які, станом на 1778 рік, становили 2/3 населення.
Родини, що проживали у селі на час обох переписів, та зміна їх чисельності¶
Отримавши дані, про національні частки населення, я провела аналіз родин, які мешкали у селі Дунаєць протягом століття проміжку між переписами, і як змінилась їх чисельність. Для початку було створено датафрейми з усіма прізвищами і їхньою кількістю
surnames_1778 = pop_1778['surname'].value_counts().reset_index()
surnames_1778
| surname | count | |
|---|---|---|
| 0 | Старченко | 71 |
| 1 | Покровський | 52 |
| 2 | Науменко | 44 |
| 3 | Цикаль | 44 |
| 4 | Бортник | 41 |
| ... | ... | ... |
| 99 | Лобач | 4 |
| 100 | Прокопець | 3 |
| 101 | Мерник | 3 |
| 102 | Ковалиха | 3 |
| 103 | Прізвище | 1 |
104 rows × 2 columns
surnames_1897 = pop_1897['surname'].value_counts().reset_index()
surnames_1897
| surname | count | |
|---|---|---|
| 0 | Старченко | 188 |
| 1 | Цигикал | 85 |
| 2 | Цигикалова | 78 |
| 3 | Овсієнко | 78 |
| 4 | Давиденко | 51 |
| ... | ... | ... |
| 176 | Горкунова | 1 |
| 177 | Ядутіна | 1 |
| 178 | Таратінова | 1 |
| 179 | Ядутін | 1 |
| 180 | Новобранний | 1 |
181 rows × 2 columns
Після цього дані з обох таблиць поєднано внутрішньо за прізвищем, а також створено окрему колоку diff з десятковими значеннями різниці (різниця того, скільки друге значення становить від першого). Прізвища були посортовані за значенням diff для зручності й читабельності
common_surnames = surnames_1778.merge(surnames_1897, on = 'surname', how = 'inner')
common_surnames.rename(columns = {'count_x': '1778', 'count_y': '1897'}, inplace = True)
common_surnames['diff'] = ((common_surnames['1897']*100/(common_surnames['1778']) - 100)/100).round(3)
common_surnames.sort_values(by = ['diff'], ascending = False, inplace = True)
sorting = common_surnames['surname'].to_list()
Переведено в довгий формат для візуалізації
common_surnames_melt = common_surnames.melt(id_vars='surname', var_name='year', value_name='count')
common_surnames_melt
| surname | year | count | |
|---|---|---|---|
| 0 | Овсієнко | 1778 | 24.000 |
| 1 | Давиденко | 1778 | 16.000 |
| 2 | Бирін | 1778 | 8.000 |
| 3 | Старченко | 1778 | 71.000 |
| 4 | Козел | 1778 | 4.000 |
| ... | ... | ... | ... |
| 79 | Корсун | diff | -0.718 |
| 80 | Гаевий | diff | -0.730 |
| 81 | Середа | diff | -0.818 |
| 82 | Бортник | diff | -0.951 |
| 83 | Ігнатенко | diff | -0.968 |
84 rows × 3 columns
Для візуалізації цього явища використовуватиму Ranged Dot Plot за допомогою бібліотеки Altair. Біля кожного прізвища стоятиме відсоток зміни відповідного кольору: червоний, якщо від'ємний, зелений -- додатний. Для зручності в орієнтації років використала розрізнення не тільки за кольором точок, а й за формою. Можна навести на точку і подивитися, саму чисельність
common_surnames['x_pos'] = common_surnames[['1778', '1897']].max(axis=1)
chart = (alt.Chart(common_surnames_melt).encode(x=alt.X("count:Q", title = 'Кількість'), y=alt.Y("surname:N", title = 'Прізвище', sort = sorting), ).transform_filter(alt.FieldOneOfPredicate(field="surname",oneOf=common_surnames['surname'],)).transform_filter(alt.FieldOneOfPredicate(field="year", oneOf=[1778, 1897])).properties(width=500, height=400, title = 'Зміна розміру родин, які проживали в селі Дунаєць, за обома переписами'))
line = chart.mark_line(color="#e8c296").encode(detail="surname:N")
color = alt.Color("year:O", title='Рік').scale(domain=[1778, 1897], range=["blue", "orange"])
points = (chart.mark_point(size=100,opacity=1,filled=True,).encode(color=color, tooltip = alt.Tooltip(['count'], title = "Кількість"), shape=alt.Shape('year', title= 'Рік').scale(range = ['circle', "triangle"])).interactive())
text = alt.Chart(common_surnames).mark_text(align="left",baseline="middle", dx=10).encode(y=alt.Y('surname:N', sort=sorting),x=alt.X('x_pos:Q'),text=alt.Text('diff:Q', format='.1%'), color=alt.condition(alt.datum['1897'] > alt.datum['1778'] ,alt.value('green'), alt.value('crimson')))
(line + points + text)
З результатів випливає, що чисельність більшості родин зменшилась, причиною чого може бути не так зменшення народжуваності(а вона була доволі високою), як виїзд родин за межі села, наприклад, у пошуках роботи або в місто. Найбільш зросла чисельність родини Освієнків, Давиденків та Биріних, за самою ж чисельністю місце залишається за родиною Старченків. Натомість, з родини Ігнатенків у 1897 році залишилась лише одна особа. В інтернеті можна знайти такі дані:
Весною 1917 року в село приїхали три чоловіки з Глухова. Староста зібрав сход. Прибулі розповіли про зміни в країні, про те, що царя скинуто, що є Тимчасовий уряд. На сході було обрано комітет уповноважених, який повинен був керувати в селі. До нього увійшли Цигикал Кирило Самосіянович, Овсієнко Семен Степанович, Давиденко Михайло та інші.
При проведенні підрахунку родин вище виявилось, що родина Цигикалів є другою найчисельнішою після Старченків.
surnames_1897[(surnames_1897['surname'] == 'Цигикал') | (surnames_1897['surname'] == 'Цигикалова')].sum(axis = 0)
surname ЦигикалЦигикалова count 163 dtype: object
Висновок¶
У цьому дослідженні було здійснено аналіз демографічної, соціальної та національно-структурної ситуації села Дунаєць Чернігівської губернії за даними переписів 1778 та 1897 років. Серед основних аспектів можна виділити:
- у віковій структурі: збільшення середньої тривалості життя, зменшення дитячої смертності, загальна симетричність між кількісним складом за статтю;
- у соціальній структурі: велика частка козацьких сімей, яка кількісно залишалась провідною. До того ж, зріс рівень заміжжя серед козаків та їх родин і відбулося зникнення одних (посполиті й бездвірні) і поява нових соціальних структур, таких як містяни і дворяни;
- у національній структурі: зростання частки росіян у структурі, зменшення чисельності родин, що проживали в селі на момент 1778 року, провідна роль найчисельніших родин у справах села.
Таким чином, проєкт відображає не лише чисельну зміну показників, а й відображає соціально-культурні трансформації в межах села Дунаєць.