<jupyter_start><jupyter_text>100 Years of Baby Names in British ColumbiaInteractive visualizations of baby names in British Columbia from 1915 to 2014. The data includes every first name that was chosen five or more times in a given year, and is published by the British Columbia Vital Statistics Agency. Raw data was downloaded from:- https://catalogue.data.gov.bc.ca/dataset/most-popular-girl-names-for-the-past-100-years- https://catalogue.data.gov.bc.ca/dataset/most-popular-boys-names-for-the-past-100-years<jupyter_code>from ipywidgets import interact, fixed
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
import seaborn as sns

import utils

sns.set_style('darkgrid')
data = utils.get_names_data(girls_file='data/bc-popular-girls-names.csv',
                            boys_file='data/bc-popular-boys-names.csv',
                            verbose=True)
print(data.shape)
data.head()
cols = ['Girls Count', 'Boys Count', 'Both Count']
grand_totals = data[cols].groupby('Name').sum()
percent = 100 * grand_totals / grand_totals.sum()
percent = percent.rename(columns={f'{nm} Count' : f'% of {nm}' for nm in ['Girls', 'Boys', 'Both']})
grand_totals = grand_totals.join(percent)
for nm in ['Girls', 'Boys']:
    grand_totals[f'{nm} Share'] = grand_totals[f'{nm} Count'] / grand_totals['Both Count']
grand_totals['Gender Gap'] = grand_totals['Girls Share'] - grand_totals['Boys Share']
grand_totals.head()
#frac_min, frac_max = 0.25, 0.75
frac_min, frac_max = 0.4, 0.6
condition = (grand_totals['Girls Share'] >= frac_min) & (grand_totals['Girls Share'] <= frac_max)
unisex = grand_totals[condition]
unisex = unisex.sort_values('Both Count', ascending=False)
percent_cols = ['% of Girls', '% of Boys', '% of Both', 'Girls Share', 'Boys Share', 'Gender Gap']
unisex.head(20).style.format('{:.2%}', subset=percent_cols)
cols = ['Boys Share', 'Girls Share']
df = unisex.head(20)
fig, axes = plt.subplots(1, 2, figsize=(9, 7), sharey=True,
                         gridspec_kw={'wspace' : 0.1, 'width_ratios' : [0.7, 0.3]})

plt.sca(axes[0])
df[cols].plot.barh(ax=plt.gca(), stacked=True)
plt.legend(frameon=True)
plt.xlim(0, 1)
plt.ylabel('')
plt.xlabel('Fraction')
plt.axvline(0.5, color='0.5')

plt.sca(axes[1])
df['Both Count'].plot.barh(ax=plt.gca(), color='0.5')
plt.gca().invert_yaxis()
plt.xlabel('Girls + Boys Count')

plt.suptitle('Top 20 Unisex Names in BC (1915-2014)', y=0.93);
def percent_ticks(axis='y', ax=None):
    if ax is None:
        ax = plt.gca()
    if axis == 'y':
        ax.yaxis.set_major_formatter(PercentFormatter())
    else:
        ax.xaxis.set_major_formatter(PercentFormatter())
def extract_year(df, year):
    return df[df['Year'] == year]
def get_top_names(df, metric='Girls Count', ntop=10):
    return df[metric].sort_values(ascending=False).head(ntop)
def plot_top_names(df, years_label='', ntop=10, metrics=['% of Girls', '% of Boys'],
                   xlabel='% of Total', figsize=(12, 4.5)):      
    fig, axes = plt.subplots(1, len(metrics), figsize=figsize)
    plt.subplots_adjust(wspace=0.5)
    for metric, ax in zip(metrics, axes):
        plt.sca(ax)
        top_names = get_top_names(df, metric=metric, ntop=ntop)
        top_names.plot.barh(ax=ax, color='C0')
        plt.gca().invert_yaxis()
        title = f'Top {ntop} {metric} Names in BC ({years_label})'.replace(' Count','').replace('% of ', '')
        plt.title(title)
        plt.ylabel('')
        plt.xlabel(xlabel)
        if '%' in xlabel:
            percent_ticks(axis='x')
ntop = 10
yrmin, yrmax = data['Year'].min(), data['Year'].max()
years_label = f'{yrmin}-{yrmax}'
plot_top_names(grand_totals, years_label=years_label, ntop=ntop)
plt.savefig('scratch/grand_totals_top10.png')
@interact(data=fixed(data), year=(1915, 2014), ntop=fixed(ntop))
def yearly_top_names(data, year=2014, ntop=10):  
    df = extract_year(data, year)
    plot_top_names(df, years_label=f'{year}', ntop=ntop)
# Number of names per year
num_names = data[data['Both Count'] > 0].reset_index()[['Year', 'Name']]
num_names = num_names.groupby('Year').count().rename(columns={'Name' : '# of Unique Names'})
num_names.plot.line()
yrmin, ymax = 2000, 2014
condition = (data['Year'] >= yrmin) & (data['Year'] <= yrmax)
df = data[condition]
ntot = df['Both Count'].sum()
df = df.groupby('Last 3 Letters').sum().sort_values('Both Count', ascending=False).head(10)
df = df['Both Count'] / ntot
df.to_frame(name='Percent of Total').style.format('{:.2%}')
yrmin, ymax = 2000, 2014
condition = (data['Year'] >= yrmin) & (data['Year'] <= yrmax)
df = data[condition]
df2 = df.groupby('Last 3 Letters').sum().sort_values('Both Count', ascending=False).head(10)
df2[['Girls Count', 'Boys Count']].plot.bar(stacked=True)
vals = list(df2.index)
pivot = df.pivot_table(index=['Last 3 Letters', 'Name'], values='Both Count', aggfunc='sum')
for val in vals:
    print('\n' + val)
    print(pivot.loc[val].sort_values('Both Count', ascending=False).head(5))
#data.groupby(['First Letter', 'Year']).sum()
pivot = data.pivot_table(index='Year', columns='First Letter', values='Both Count')
pivot.plot.line(figsize=(20, 10))
cols = ['First Letter', 'Girls Count', 'Boys Count', 'Both Count']
first_letter_totals = data[cols].groupby('First Letter').sum().sort_values('Both Count', ascending=False)
first_letter_totals[['Boys Count', 'Girls Count']].plot.bar(figsize=(12, 4), stacked=True)
data[data['First Letter'] == 'J'].groupby('Year').sum()[['Boys Count', 'Girls Count']].plot.line()
data[data['Last 3 Letters'] == 'DEN'].groupby('Year').sum()[['Boys Count', 'Girls Count']].plot.line()<jupyter_output><empty_output><jupyter_text>Stuff to doWrite a function to extract a subset of years from the dataframe and use a range slider widget to plot aggregates for the selected years of unisex names, top girl names, top boy names, etc.<jupyter_code>#names = ['EMMA', 'JENNIFER', 'MARY', 'OLIVIA', 'SARAH', 'SOPHIA']
names = ['JENNIFER', 'MARY', 'PATRICIA', 'MARGARET', 'OLIVIA', 'EMMA', 'SARAH']
metric =  '% of Girls'
df = data.loc[names, ['Year', metric]].reset_index().set_index('Year')
df = df.pivot(columns='Name')
df.columns = df.columns.droplevel(0)
df.columns = sorted(df.columns)

df.plot.line()
plt.ylabel(metric)
plt.gca().yaxis.set_major_formatter(PercentFormatter())
plt.title('Baby Girl Names in BC')
#plt.grid(color='0.8')
#plt.savefig('scratch/some_girls_names.png')
plt.savefig('scratch/some_girls_names2.png')
names = ['ROBERT', 'DAVID', 'MICHAEL', 'JOHN', 'ETHAN', 'DEREK']
metric =  '% of Boys'
df = data.loc[names, ['Year', metric]].reset_index().set_index('Year')
df = df.pivot(columns='Name')
df.columns = df.columns.droplevel(0)
df.columns = sorted(df.columns)

df.plot.line()
plt.ylabel(metric)
plt.gca().yaxis.set_major_formatter(PercentFormatter())
plt.grid(color='0.8')
plt.savefig('scratch/some_boys_names.png')
names = ['FANNY', 'ANNE', 'ANNA', 'DEBBIE', 'MABEL']
metric =  '% of Girls'
df = data.loc[names, ['Year', metric]].reset_index().set_index('Year')
df = df.pivot(columns='Name')
df.columns = df.columns.droplevel(0)
df.columns = sorted(df.columns)

df.plot.line()
plt.ylabel(metric)
plt.gca().yaxis.set_major_formatter(PercentFormatter())
plt.grid(color='0.8')
plt.savefig('scratch/fanny_and_others.png')
names = ['DEREK', 'LUCAS', 'ETHAN', 'LIAM']
metric =  '% of Boys'
df = data.loc[names, ['Year', metric]].reset_index().set_index('Year')
df = df.pivot(columns='Name')
df.columns = df.columns.droplevel(0)
df.columns = sorted(df.columns)

df.plot.line()
plt.ylabel(metric)
plt.gca().yaxis.set_major_formatter(PercentFormatter())
plt.grid(color='0.8')
plt.savefig('scratch/derek_and_others.png')
data[data.index.isin(['JENNIFER', 'JOHN', 'JORDAN', 'MORGAN']) & (data['Year'] == 1995)]

# Add some code to find and analyze unisex names
cols = ['Girls Count', 'Boys Count', 'Both Count']
sort_by = 'Boys Count'
data[cols].groupby('Name').sum().sort_values(sort_by, ascending=False).head(10)
year = 1915
sort_by = 'Boys Count'
data[data['Year'] == year].sort_values(sort_by, ascending=False).head(10)
cols = ['Year', 'Girls Count', 'Boys Count', 'Both Count']
rankings = data[cols].groupby(['Name', 'Year']).rank(ascending=False)
rankings.head()
year = 1981
metric = 'Girls Count'
series = data.loc[(data['Year'] == year) & (data[metric] > 0), metric]
series.rank(ascending=False).sort_values().head(10)
year = 1915
metric = 'Boys Count'
series = data.loc[(data['Year'] == year) & (data[metric] > 0), metric]
series.rank(ascending=False).sort_values().head(10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.18882263533263183, 'fraction_numerical': 0.020343739038933707, 'mean_word_length': 5.383582089552239, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '469023', 'license': 'MIT', 'n_tokens_mistral': 3355, 'n_tokens_neox': 3122, 'n_words': 657, 'path': 'Baby Names.ipynb', 'repo_name': 'jenfly/bc-baby-names', 'size': '8553'}