Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Pozdravljeni, Habr!

Danes bomo delali na veščini uporabe orodij za združevanje in vizualizacijo podatkov v Pythonu. V predvidenem nabor podatkov na Githubu Analizirajmo več značilnosti in zgradimo nabor vizualizacij.

Po tradiciji na začetku določimo cilje:

  • Združite podatke po spolu in letu ter vizualizirajte celotno dinamiko rodnosti obeh spolov;
  • Poiščite najbolj priljubljena imena vseh časov;
  • Celotno časovno obdobje v podatkih razdelite na 10 delov in za vsakega poiščite najbolj priljubljeno ime vsakega spola. Za vsako najdeno ime vizualizirajte njegovo dinamiko skozi ves čas;
  • Za vsako leto izračunajte, koliko imen pokriva 50 % ljudi in vizualizirajte (videli bomo raznolikost imen za vsako leto);
  • Iz celotnega intervala izberite 4 leta in za vsako leto prikažite porazdelitev po prvi črki v imenu in po zadnji črki v imenu;
  • Naredite seznam več znanih oseb (predsednikov, pevcev, igralcev, filmskih likov) in ocenite njihov vpliv na dinamiko imen. Zgradite vizualizacijo.

Manj besed, več kode!

In gremo.

Združimo podatke po spolu in letu ter vizualizirajmo skupno dinamiko rodnosti obeh spolov:

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='Мужчины')
stolb2 = ax.bar(index + 0.4, births_women_list, 0.4, alpha=0.8, color='r', label='Женщины')

ax.set_title('Рождаемость по полу и годам')
ax.set_xlabel('Года')
ax.set_ylabel('Рождаемость')
ax.set_xticklabels(years)
ax.set_xticks(index + 0.4)
ax.legend(loc=9)

fig.tight_layout()
plt.show()

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Poiščimo najbolj priljubljena imena v zgodovini:

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)

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Razdelimo celotno časovno obdobje v podatkih na 10 delov in za vsakega bomo našli najbolj priljubljeno ime posameznega spola. Za vsako najdeno ime vizualiziramo njegovo dinamiko skozi ves čas:

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('Года')
    ax.set_ylabel('Рождаемость')
    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()

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Za vsako leto izračunamo, koliko imen pokriva 50 % ljudi, in vizualiziramo te podatke:

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('Года', fontsize = 12)
ax1.set_ylabel('Разнообразие имен', fontsize = 12)
ax1.plot(dataframe['year'], dataframe['count'], color='r', ls='-')
ax1.legend(loc=9, fontsize=12)

plt.show()

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Iz celotnega intervala izberimo 4 leta in za vsako leto izpišemo porazdelitev po prvi črki v imenu in po zadnji črki v imenu:

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('Буква алфавита')
ax_first.set_ylabel('Частота, %')
ax_first.set_title('Первая буква в имени')
ax_first.set_xticks(index)
ax_first.set_xticklabels(ascii_uppercase)
ax_first.legend()

ax_last.set_xlabel('Буква алфавита')
ax_last.set_ylabel('Частота, %')
ax_last.set_title('Последняя буква в имени')
ax_last.set_xticks(index)
ax_last.set_xticklabels(ascii_uppercase)
ax_last.legend()

fig_first.tight_layout()
fig_last.tight_layout()

plt.show()

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Naredimo seznam več znanih ljudi (predsednikov, pevcev, igralcev, filmskih likov) in ocenimo njihov vpliv na dinamiko imen:

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('Года', fontsize = 10)
    ax.set_ylabel('Рождаемость', fontsize = 10)
    ax.plot(dataframe['year'], dataframe['count'], label=celebrity, color='r', ls='-')
    ax.legend(loc=9, fontsize=12)
        
    plt.show()

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Delo na veščini uporabe združevanja in vizualizacije podatkov v Pythonu

Za trening lahko vizualizaciji iz zadnjega primera dodate življenjsko obdobje zvezdnika, da jasno ocenite njihov vpliv na dinamiko imen.

S tem so bili doseženi in izpolnjeni vsi naši cilji. Razvili smo veščino uporabe orodij za združevanje in vizualizacijo podatkov v Pythonu, delo s podatki pa bomo nadaljevali. Vsak lahko sam sklepa na podlagi že pripravljenih, vizualiziranih podatkov.

Znanje vsem!

Vir: www.habr.com

Dodaj komentar