Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Hello, Habr!

Danes bomo obravnavali veščino uporabe sredstev za grupiranje in vizualizacijo podatkov v Pythonu. V predloženem naboru podatkov na GitHubu bomo analizirali več značilnosti in ustvarili niz vizualizacij.

Po tradiciji, na začetku, določimo cilje:

  • Grupirati podatke po spolu in letu ter vizualizirati skupno dinamiko rodnosti obeh spolov;
  • Najti najbolj priljubljena imena v zgodovini;
  • Razdeliti celoten časovni razpon v podatkih na 10 delov in za vsak del najti najbolj priljubljeno ime vsakega spola. Za vsako najdeno ime vizualizirati njegovo dinamiko skozi čas;
  • Za vsak leto izračunati koliko imen pokriva 50% ljudi in vizualizirati (videli bomo raznolikost imen vsako leto);
  • Izbrati 4 leta iz celotnega obdobja in prikazati za vsako leto porazdelitev po prvi in zadnji črki imena;
  • Sestaviti seznam znanih osebnosti (predsedniki, pevci, igralci, filmski junaki) in oceniti njihov vpliv na dinamiko imen. Ustvariti nazorno vizualizacijo.

Manj besed, več kode!

In gremo.

Grupirajmo 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='Moški')
stolb2 = ax.bar(index + 0.4, births_women_list, 0.4, alpha=0.8, color='r', label='Ženske')

ax.set_title('Rodnost po spolu in letih')
ax.set_xlabel('Leta')
ax.set_ylabel('Rodnost')
ax.set_xticklabels(years)
ax.set_xticks(index + 0.4)
ax.legend(loc=9)

fig.tight_layout()
plt.show()

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Najdimo 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)

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Razdelimo celoten časovni razpon podatkov na 10 delov in za vsak del najdemo najbolj priljubljeno ime za vsak spol. Za vsako najdeno ime vizualiziramo njegovo dinamiko skozi vsa leta:

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('Leta')
    ax.set_ylabel('Rodnost')
    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()

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Za vsako leto bomo izračunali, koliko imen pokriva 50 % ljudi in te podatke vizualizirali:

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('Leta', fontsize = 12)
ax1.set_ylabel('Raznolikost imen', fontsize = 12)
ax1.plot(dataframe['year'], dataframe['count'], color='r', ls='-')
ax1.legend(loc=9, fontsize=12)

plt.show()

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Izbrali bomo 4 leta iz celotnega razpona in za vsako leto prikazali razporeditev po prvi in zadnji črki imena:

iz stringe 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('Črka abecede')
ax_first.set_ylabel('Frekvenca, %')
ax_first.set_title('Prva črka v imenu')
ax_first.set_xticks(index)
ax_first.set_xticklabels(ascii_uppercase)
ax_first.legend()

ax_last.set_xlabel('Črka abecede')
ax_last.set_ylabel('Frekvenca, %')
ax_last.set_title('Zadnja črka v imenu')
ax_last.set_xticks(index)
ax_last.set_xticklabels(ascii_uppercase)
ax_last.legend()

fig_first.tight_layout()
fig_last.tight_layout()

plt.show()

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Naredimo seznam nekaj znanih oseb (predsedniki, pevci, igralci, filmski junaki) 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('Leta', fontsize = 10)
    ax.set_ylabel('Rodnost', fontsize = 10)
    ax.plot(dataframe['year'], dataframe['count'], label=celebrity, color='r', ls='-')
    ax.legend(loc=9, fontsize=12)
        
    plt.show()

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Usavršavamo vještinu korištenja grupiranja i vizualizacije podataka u Pythonu

Za vadbo lahko iz zadnjega primera dodate v vizualizacijo obdobje življenja znane osebe, da boste lažje ocenili njihov vpliv na dinamiko imen.

Tukaj so bili vsi naši cilji doseženi in izpolnjeni. Obvladali smo veščino uporabe sredstev za grupiranje in vizualizacijo podatkov v Pythonu ter nadaljevali z delom s podatki. Ugotovitve na že pripravljenih, vizualiziranih podatkih lahko vsak izpelje sam.

Vsem znanja!

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster