
Hallo, Habr!
Heute werden wir die Fertigkeit der Datenaggregation und -visualisierung in Python entwickeln. In dem bereitgestellten analysieren wir mehrere Merkmale und erstellen eine Reihe von Visualisierungen.
Wie gewohnt beginnen wir mit den Zielen:
- Die Daten nach Geschlecht und Jahr zu gruppieren und die allgemeine Geburtenentwicklung beider Geschlechter zu visualisieren;
- Die beliebtesten Namen aller Zeiten zu finden;
- Den gesamten Zeitraum in den Daten in 10 Teile zu unterteilen und für jeden das beliebteste Namen jedes Geschlechts zu ermitteln. Die Dynamik jedes gefundenen Namens über die gesamte Zeit zu visualisieren;
- Für jedes Jahr zu berechnen, wie viele Namen 50% der Bevölkerung abdecken, und dies zu visualisieren (wir werden die Vielfalt der Namen jedes Jahr sehen);
- Vier Jahre aus dem gesamten Zeitraum auszuwählen und für jedes Jahr die Verteilung nach dem ersten und letzten Buchstaben des Namens darzustellen;
- Eine Liste von mehreren bekannten Personen (Präsidenten, Sänger, Schauspieler, Filmfiguren) zu erstellen und ihren Einfluss auf die Namensentwicklung zu bewerten. Eine anschauliche Visualisierung zu erstellen.
Weniger Worte, mehr Code!
Und los geht's.
Wir gruppieren die Daten nach Geschlecht und Jahr und visualisieren die Gesamtgeburtenentwicklung beider Geschlechter:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
years = np.arange(1880, 2011, 3)
datalist = 'https://raw.githubusercontent.com/wesm/pydata-book/2nd-edition/datasets/babynames/yob{year}.txt'
dataframes = []
for year in years:
dataset = datalist.format(year=year)
dataframe = pd.read_csv(dataset, names=['name', 'sex', 'count'])
dataframes.append(dataframe.assign(year=year))
result = pd.concat(dataframes)
sex = result.groupby('sex')
births_men = sex.get_group('M').groupby('year', as_index=False)
births_women = sex.get_group('F').groupby('year', as_index=False)
births_men_list = births_men.aggregate(np.sum)['count'].tolist()
births_women_list = births_women.aggregate(np.sum)['count'].tolist()
fig, ax = plt.subplots()
fig.set_size_inches(25,15)
index = np.arange(len(years))
stolb1 = ax.bar(index, births_men_list, 0.4, color='c', label='Männer')
stolb2 = ax.bar(index + 0.4, births_women_list, 0.4, alpha=0.8, color='r', label='Frauen')
ax.set_title('Geburten nach Geschlecht und Jahr')
ax.set_xlabel('Jahr')
ax.set_ylabel('Geburten')
ax.set_xticklabels(years)
ax.set_xticks(index + 0.4)
ax.legend(loc=9)
fig.tight_layout()
plt.show()

Lassen Sie uns die beliebtesten Namen in der gesamten Geschichte finden:
years = np.arange(1880, 2011)
dataframes = []
for year in years:
dataset = datalist.format(year=year)
dataframe = pd.read_csv(dataset, names=['name', 'sex', 'count'])
dataframes.append(dataframe)
result = pd.concat(dataframes)
names = result.groupby('name', as_index=False).sum().sort_values('count', ascending=False)
names.head(10)

Wir unterteilen den gesamten Zeitrahmen der Daten in 10 Abschnitte und finden für jeden das beliebteste Name jedes Geschlechts. Für jedes gefundene Name visualisieren wir dessen Entwicklung über die gesamte Zeit:
years = np.arange(1880, 2011)
part_size = int((years[years.size - 1] - years[0]) / 10) + 1
parts = {}
def GetPart(year):
return int((year - years[0]) / part_size)
for year in years:
index = GetPart(year)
r = years[0] + part_size * index, min(years[years.size - 1], years[0] + part_size * (index + 1))
parts[index] = str(r[0]) + '-' + str(r[1])
dataframe_parts = []
dataframes = []
for year in years:
dataset = datalist.format(year=year)
dataframe = pd.read_csv(dataset, names=['name', 'sex', 'count'])
dataframe_parts.append(dataframe.assign(years=parts[GetPart(year)]))
dataframes.append(dataframe.assign(year=year))
result_parts = pd.concat(dataframe_parts)
result = pd.concat(dataframes)
result_parts_sums = result_parts.groupby(['years', 'sex', 'name'], as_index=False).sum()
result_parts_names = result_parts_sums.iloc[result_parts_sums.groupby(['years', 'sex'], as_index=False).apply(lambda x: x['count'].idxmax())]
result_sums = result.groupby(['year', 'sex', 'name'], as_index=False).sum()
for groupName, groupLabels in result_parts_names.groupby(['name', 'sex']).groups.items():
group = result_sums.groupby(['name', 'sex']).get_group(groupName)
fig, ax = plt.subplots(1, 1, figsize=(18,10))
ax.set_xlabel('Jahre')
ax.set_ylabel('Geburtenrate')
label = group['name']
ax.plot(group['year'], group['count'], label=label.aggregate(np.max), color='b', ls='-')
ax.legend(loc=9, fontsize=11)
plt.show()










Für jedes Jahr berechnen wir, wie viele Namen 50 % der Menschen abdecken, und visualisieren diese Daten:
dataframe = pd.DataFrame({'year': [], 'count': []})
years = np.arange(1880, 2011)
for year in years:
dataset = datalist.format(year=year)
csv = pd.read_csv(dataset, names=['name', 'sex', 'count'])
names = csv.groupby('name', as_index=False).aggregate(np.sum)
names['sum'] = names.sum()['count']
names['percent'] = names['count'] / names['sum'] * 100
names = names.sort_values(['percent'], ascending=False)
names['cum_perc'] = names['percent'].cumsum()
names_filtered = names[names['cum_perc'] <= 50]
dataframe = dataframe.append(pd.DataFrame({'year': [year], 'count': [names_filtered.shape[0]]}))
fig, ax1 = plt.subplots(1, 1, figsize=(22,13))
ax1.set_xlabel('Jahre', fontsize = 12)
ax1.set_ylabel('Vielfalt der Namen', fontsize = 12)
ax1.plot(dataframe['year'], dataframe['count'], color='r', ls='-')
ax1.legend(loc=9, fontsize=12)
plt.show()

Wählen wir 4 Jahre aus dem gesamten Zeitraum aus und zeigen für jedes Jahr die Verteilung nach dem ersten und dem letzten Buchstaben des Namens an:
from string import ascii_lowercase, ascii_uppercase
fig_first, ax_first = plt.subplots(1, 1, figsize=(14,10))
fig_last, ax_last = plt.subplots(1, 1, figsize=(14,10))
index = np.arange(len(ascii_uppercase))
years = [1944, 1978, 1991, 2003]
colors = ['r', 'g', 'b', 'y']
n = 0
for year in years:
dataset = datalist.format(year=year)
csv = pd.read_csv(dataset, names=['name', 'sex', 'count'])
names = csv.groupby('name', as_index=False).aggregate(np.sum)
count = names.shape[0]
dataframe = pd.DataFrame({'letter': [], 'frequency_first': [], 'frequency_last': []})
for letter in ascii_uppercase:
countFirst = (names[names.name.str.startswith(letter)].count()['count'])
countLast = (names[names.name.str.endswith(letter.lower())].count()['count'])
dataframe = dataframe.append(pd.DataFrame({
'letter': [letter],
'frequency_first': [countFirst / count * 100],
'frequency_last': [countLast / count * 100]}))
ax_first.bar(index + 0.3 * n, dataframe['frequency_first'], 0.3, alpha=0.5, color=colors[n], label=year)
ax_last.bar(index + bar_width * n, dataframe['frequency_last'], 0.3, alpha=0.5, color=colors[n], label=year)
n += 1
ax_first.set_xlabel('Buchstabe des Alphabets')
ax_first.set_ylabel('Häufigkeit, %')
ax_first.set_title('Erster Buchstabe im Namen')
ax_first.set_xticks(index)
ax_first.set_xticklabels(ascii_uppercase)
ax_first.legend()
ax_last.set_xlabel('Buchstabe des Alphabets')
ax_last.set_ylabel('Häufigkeit, %')
ax_last.set_title('Letzter Buchstabe im Namen')
ax_last.set_xticks(index)
ax_last.set_xticklabels(ascii_uppercase)
ax_last.legend()
fig_first.tight_layout()
fig_last.tight_layout()
plt.show()


Lassen Sie uns eine Liste von bekannten Persönlichkeiten (Präsidenten, Sänger, Schauspieler, Filmfiguren) erstellen und ihren Einfluss auf die Namensvergabe bewerten:
celebrities = {'Frank': 'M', 'Britney': 'F', 'Madonna': 'F', 'Bob': 'M'}
dataframes = []
for year in years:
dataset = datalist.format(year=year)
dataframe = pd.read_csv(dataset, names=['name', 'sex', 'count'])
dataframes.append(dataframe.assign(year=year))
result = pd.concat(dataframes)
for celebrity, sex in celebrities.items():
names = result[result.name == celebrity]
dataframe = names[names.sex == sex]
fig, ax = plt.subplots(1, 1, figsize=(16,8))
ax.set_xlabel('Jahre', fontsize = 10)
ax.set_ylabel('Geburtenrate', fontsize = 10)
ax.plot(dataframe['year'], dataframe['count'], label=celebrity, color='r', ls='-')
ax.legend(loc=9, fontsize=12)
plt.show()




Für das Training können Sie aus dem letzten Beispiel den Lebenszeitraum der Berühmtheit zur Visualisierung hinzufügen, um deren Einfluss auf die Namensdynamik anschaulich zu bewerten.
Damit sind alle unsere Ziele erreicht und erfüllt. Wir haben die Fähigkeit zur Gruppierung und Visualisierung von Daten in Python trainiert und werden weiter mit den Daten arbeiten. Jeder kann aus den bereits vorbereiteten, visualisierten Daten seine eigenen Schlussfolgerungen ziehen.
Allen viel Wissen!
Quelle: habr.com
