#!/usr/bin/env python
# coding: utf-8
# Anecdotes autours des prénoms
# ====
#
# Les données peuvent être téléchargées sur [data.gouv.fr](https://www.data.gouv.fr/fr/datasets/fichier-des-prenoms-edition-2016/) (merci Vince B pour le format csv)
#
# Ce notebook étudie différentes questions sur les prénoms :
# * [Combien de lettres ont les prénoms ? Quels sont les plus long ?](#longueur)
# * [Est-ce que les prénoms donnés sont de plus en plus courts ?](#plus_courts)
# * [Où en est la mode des noms composés ? Quels sont les plus donnés ?](#noms_composes)
# * [Est-ce que les gens nomment leurs enfants en fonction des stars ?](#star_system)
# * [Quelles est la dynamique des prénoms qui sont à la fois des prénoms de garçons et de filles ?](#double_genre)
#
#
# N'hésitez pas à profiter du côté collaboratif de github pour me faire parvenir vos idées, vos remarques et votre code !
# In[1]:
import os
import pandas as pd
get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
path = 'D:\data\prénom'
# In[2]:
for tab in ['nat2015']:
path_file = os.path.join(path, tab + '.dbf')
csv_file = os.path.join(path, tab + '.csv')
nat = pd.read_csv(csv_file)
nat['prenom'] = nat['preusuel']
del nat['preusuel']
# on retire les XXX
nat = nat[nat.annais != 'XXXX']
nat['annais'] = nat['annais'].astype(int)
nat['genre'] = 'feminin'
nat['genre'][nat['sexe'] == 1] = 'masculin'
del nat['sexe']
nat = nat[nat['prenom'].notnull()]
#
# Longueurs des prénoms
# ====
#
# ## L'état actuel
# => La moyenne est à 6,6 lettres par prénoms
#
# * Le petit pic à 15 correspond est dû aux 75 000 MARIE-CHRISTINE, aux 31 000 JEAN-CHRISTOPHE et au 28 000 MARIE-FRANÇOISE. A 14 lettres, les JEAN-SÉBASTIEN et les ANNE-CHARLOTTE sont 5 000, à 16 lettres, les MARIE-ANTOINETTE sont 7 500.
# In[3]:
# taille des prénom
nat['longueur'] = nat['prenom'].str.len().astype(int)
nat = nat[nat['prenom'] != '_PRENOMS_RARES']
nat.groupby('longueur')['nombre'].sum().plot.bar()
# In[4]:
# pour regarde les noms par taille
nat[nat['longueur'] == 15]['prenom'].nunique()
nat[nat['longueur'] == 16].groupby('prenom')['nombre'].sum().sort_values().tail()
# In[5]:
# les prenoms les plus long
print('Les noms les plus longs')
print(nat[nat.prenom.str.len() > 15]['prenom'].unique().tolist()[:9])
# c'est des noms composés
# les plus longs des plus longs
print('\n les plus longs des plus longs')
print(nat[nat.prenom.str.len() == 19]['prenom'].unique().tolist()[:9])
longueur_du_premier_nom = nat['prenom'].str.split('-').str[0].str.len().astype(int)
print('\n Les plus longs prénoms non-composés (13 lettres)')
print(nat[longueur_du_premier_nom == 13]['prenom'].unique().tolist())
print('\n Prénoms non-composés de 12 lettres')
print(nat[longueur_du_premier_nom ==12]['prenom'].unique().tolist())
#
# ## Est-ce que l'on donne des noms de plus en plus courts ?
# In[6]:
import colorsys
# des prénoms de plus en plus courts ?
grouped_longueur = 2*(nat['longueur'] // 2)
grouped_longueur[grouped_longueur == 0] = 1
nat['grouped_longueur'] = grouped_longueur.astype(str) + '-' + (grouped_longueur + 1).astype(str) + ' lettres'
by_long = nat.groupby(['annais', 'grouped_longueur'])['nombre'].sum()
by_long = pd.DataFrame(by_long).reset_index()
# print(by_long)
#by_long.plot(stacked=True, kind='bar')
fig, ax = plt.subplots(figsize=(16,12))
idx = 0
for long, group in by_long.groupby('grouped_longueur'):
color = colorsys.hsv_to_rgb((3 + float(long.split('-')[0]))*19/360, 1., 1.)
group.plot(x='annais', y='nombre', kind='line', ax=ax, label = long,
color= color)
# ### Oui ! Les prénoms de 3 lettres augmentent depuis les années 2000. Ceux de 4 et 5 lettres aussi beaucoup depuis les années 1980 pendant que les noms de 6 lettres et plus baissent.
#
# Sur le graphique ci-dessous, on voit que la longueur moyenne des prénoms était de 7,2 lettres en
# 1960, c'est 5,4 en 2015.
#
# L'augmentation du milieu du siècle est du à la diffusion des noms-composés (voir plus bas).
# In[7]:
longueur_moyenne_par_annee = nat.groupby(['annais']).apply(
lambda x: (x['longueur']*x['nombre']).sum()/x['nombre'].sum()
)
longueur_moyenne_par_annee.plot()
#
#
# # Histoire des noms composés
# In[8]:
nat['compose'] = nat['prenom'].str.contains('-')
print(nat['compose'].value_counts())
nat[nat['compose']]
composes = nat[nat['compose']]
composes.groupby('annais').sum().reset_index().plot(x='annais', y='nombre')
# In[9]:
# qui sont les rocks star des noms composés ?
composes['nom1'] = composes['prenom'].str.split('-').str[0]
composes['nom2'] = composes['prenom'].str.split('-').str[1]
print('\n Les 10 prénoms composés les plus répandus')
print(composes.groupby('prenom')['nombre'].sum().sort_values(ascending=False).head(10))
print('\n Les 10 premières partie de prénoms composés les plus répandus')
print(composes.groupby('nom1')['nombre'].sum().sort_values(ascending=False).head(10))
print('\n Les 10 secondes partie de prénoms composés les plus répandus')
print(composes.groupby('nom2')['nombre'].sum().sort_values(ascending=False).head(10))
print("\n Remarque : Trois prénoms ont trois mots. Il s'agit de", composes[composes['prenom'].str.split('-').str[2].notnull()]['prenom'].unique())
#
#
# # Les prénoms donnés sont-ils influencés par les stars du moment ?
#
# On regare Zinedine, Alizée (et Lolita :) ), Karl, Omar, ou encore BARACK
# In[10]:
def plot_prenom_startswith(debut_prenom):
prenom_de_star = nat.prenom.str.startswith(debut_prenom)
print(nat.prenom[prenom_de_star].unique())
nat[prenom_de_star].groupby('annais')['nombre'].sum().plot(x='annais', y='nombre')
# In[11]:
# Effet Zizou en 1998 ( avec un pic à 200)
nat.prenom.value_counts()
nat[nat.prenom == "ZINEDINE"].plot(x='annais', y='nombre')
# In[12]:
# Alizé sort son tube Lolita en 2000
prenom_de_star = nat.prenom.str.startswith('ALIZÉ')
print(nat.prenom[prenom_de_star].unique())
nat[prenom_de_star].groupby('annais')['nombre'].sum().plot(x='annais', y='nombre')
prenom_de_star = nat.prenom.str.startswith('LOLIT')
print(nat.prenom[prenom_de_star].unique())
nat[prenom_de_star].groupby('annais')['nombre'].sum().plot(x='annais', y='nombre')
# In[13]:
# Barack Obama
plot_prenom_startswith('BARA')
# In[14]:
# L'étonnant prénom KARL : trop allemand avant 1968 et hommage à Karl Marx ensuite ?
# Notez un petit pic en 2006
nat[nat.prenom == "KARL"].plot(x='annais', y='nombre')
# In[15]:
# La folle histoire du prénom Omar.
# C'est mon interprétation mais il semble il y avoir une tendance de fond, ralentie par l'épisode "Omar m'a tuer" que la bonne humeur
# d'Omar Sy fait oublier
plot_prenom_startswith('OMAR')
#
#
# # Les prénoms qui sont à la fois des prénoms de filles et de garçons
#
# Des histoires très différentes. Dominique a été donné à peu près de la même façon aux filles et aux garçons.
# Camille était plutôt masculin au début du siècle et est devenu plutôt féminin. Evolution inverse avec le prénom EDEN qui est peut-être boosté par la popularité du joueur de foot EDEN HAZAR pour les garçons plus que pour les filles.
#
# Dans les prénoms "unisexe" les plus donnés, figure Charlie qui a connu une baisse très forte en 2015.
#
# In[16]:
# prénom des deux genres
genres = nat.groupby('prenom')['genre'].nunique()
double_genre = genres[genres == 2]
double_genre = double_genre.index.tolist()
# double_genre.remove("_PRENOMS_RARES")
double_genre = nat[nat['prenom'].isin(double_genre)]
# In[17]:
gp = double_genre.groupby(['prenom', 'genre'])['nombre'].sum()
ratio = gp.groupby(level=0).apply(lambda x: 100*x/float(x.sum()))
# In[18]:
condtition_mitige = (ratio > 20) & (ratio < 80)
mitige = ratio[condtition_mitige].reset_index()
list_mitige = mitige['prenom']
genre_mitige = nat[nat['prenom'].isin(list_mitige)]
genre_mitige.groupby('prenom')['nombre'].sum().sort_values(ascending=False).head(10)
# In[19]:
def plot_prenom(prenom):
fig, ax = plt.subplots(figsize=(8,6))
prenom_tab = nat[nat.prenom == prenom]
title = "Evolution par genre du prénom {}".format(prenom)
# print(prenom_tab)
#print(prenom, prenom_tab.groupby('genre')['nombre'].sum())
grp = prenom_tab.groupby('genre')
for label, data in grp:
data.plot(x='annais', y='nombre', kind='line', ax=ax, title=title, label=label)
for prenom in genre_mitige.groupby('prenom')['nombre'].sum().sort_values(ascending=False).index.tolist()[:15]:
plot_prenom(prenom)