Netflix heeft onlangs gebruikersbeoordelingen vrijgegeven. Ik wilde een eenvoudige vraag stellen: geven Netflix-abonnees de voorkeur aan oudere of nieuwere films?
Intuïtief wil je de dataset opsplitsen in groepen, één voor elk jaar, vervolgens een samenvattende statistiek berekenen, zoals het gemiddelde of de mediaan, en dan kijken of deze statistiek over de jaren toeneemt (daarna wil je misschien een statistische toets uitvoeren).
Het mooie is dat er een conceptueel kader voor bestaat, met implementaties in zowel Python als R. Dit kader staat bekend als "split-apply-combine" omdat we...
Stap 1: de data in groepen splitsen door een groupby-object te maken van de oorspronkelijke DataFrame;
Stap 2: een functie toepassen, in dit geval een aggregatiefunctie die een samenvattende statistiek berekent (je kunt in deze stap ook je data transformeren of filteren);
Stap 3: de resultaten combineren in een nieuwe DataFrame.
Dit is het conceptuele kader voor de analyse die we gaan doen. In deze post leer je hoe je dit toepast om de Netflix-vraag hierboven te beantwoorden met behulp van het Python-pakket pandas. Je kunt hetzelfde in R doen met bijvoorbeeld het pakket dplyr. Ik ga ook noodgedwongen in op groupby-objecten, die niet de meest intuïtieve objecten zijn. Het split-apply-combine-proces met groupby-objecten is een patroon dat we allemaal intuïtief uitvoeren, zoals we zullen zien, maar het was Hadley Wickham die de procedure in 2011 formaliseerde met zijn paper The Split-Apply-Combine Strategy for Data Analysis.
Hier gebruik je pandas, groupby-objecten en de principes van split-apply-combine om te bekijken hoe de Netflix-filmscores variëren als functie van het jaar waarin ze zijn uitgebracht. Ik kwam de data oorspronkelijk tegen op data.world hier. Je vindt alle code in deze post hier als je het wilt reproduceren.
Je importeert eerst de benodigde pakketten en de data en bekijkt de eerste vijf rijen van de data:
# Import packages and set visualization styleimport pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()%matplotlib inline
Mogelijk gemaakt door
# Import data and check out head of DataFrame
df = pd.read_csv('data/chasewillden-netflix-shows/data/netflix.csv')
df.head()Mogelijk gemaakt door
title
rating
ratinglevel
ratingdescription
release_year
user_rating_score
user_rating_size
0
White Chicks
PG-13
crude and sexual humor, language and some drug...
80
2004
82.0
80
1
Lucky Number Slevin
R
strong violence, sexual content and adult lang...
100
2006
NaN
82
2
Grey's Anatomy
TV-14
Parents strongly cautioned. May be unsuitable ...
90
2016
98.0
80
3
Prison Break
TV-14
Parents strongly cautioned. May be unsuitable ...
90
2008
98.0
80
4
How I Met Your Mother
TV-PG
Parental guidance suggested. May not be suitab...
70
2014
94.0
80
Dit ziet er prima uit: je hebt titels, classificaties, uitbrengjaar en gebruikersscore, naast diverse andere kolommen. Voordat we onze groupby- en split-apply-combine-procedure uitvoeren, kijken we iets nauwkeuriger naar de data om zeker te weten dat die is wat we denken en om met missende waarden om te gaan. Merk op dat er een missende waarde NaN staat in de user_rating_score van de tweede rij (rij 1).
Je data samenvatten met grafieken en statistieken
De pandas DataFrame-methode .info() is onmisbaar. Toepassen hieronder laat zien dat je 1000 rijen en 7 kolommen hebt, maar ook dat de kolom van belang, user_rating_score, slechts 605 niet-lege waarden heeft. Dit betekent dat er 395 missende waarden zijn:
<class'pandas.core.frame.DataFrame'>RangeIndex:1000 entries,0 to 999
Data columns(total 7 columns):
title 1000 non-null object
rating 1000 non-null object
ratinglevel 941 non-null object
ratingdescription 1000 non-null int64
release_year 1000 non-null int64
user_rating_score 605 non-null float64
user_rating_size 1000 non-null int64
dtypes:float64(1),int64(3),object(3)
memory usage:54.8+KBMogelijk gemaakt door
Je kunt rijen met missende waarden droppen, dubbele rijen verwijderen en een pairplot van de DataFrame maken met seaborn om een visueel gevoel voor de data te krijgen. Je kleurt de data op basis van de kolom 'rating'. Bekijk de grafieken en kijk welke informatie je eruit haalt.
# Drop rows with missing values and drop duplicate
df.dropna(inplace=True)
df.drop_duplicates(inplace=True)# Visualize pairplot of df
sns.pairplot(df, hue='rating');Mogelijk gemaakt door
Bekijk bijvoorbeeld user_rating_score als functie van release_year. Er is geen visueel duidelijke trend, maar wellicht brengt wat data-analyse trends naar voren. Als je verschillende samenvattende statistieken van de DataFrame wilt bekijken, kan dat ook met de methode .describe():
Groupbys en split-apply-combine om de vraag te beantwoorden
Stap 1. Split
Nu je de data hebt verkend, is het tijd voor het leuke gedeelte. Je gebruikt eerst een groupby-methode om de data op te splitsen in groepen, waarbij elke groep de set films is die in een bepaald jaar zijn uitgebracht. Dit is de split in split-apply-combine:
Dergelijke groupby-objecten zijn erg nuttig. Weet je nog dat de methode .describe() voor een DataFrame samenvattende statistieken voor numerieke kolommen teruggeeft? Welnu, de methode .describe() voor DataFrameGroupBy-objecten geeft samenvattende statistieken voor elke numerieke kolom, maar dan per groep in de split. In jouw geval is dat per release_year. Dit is een voorbeeld van de apply in split-apply-combine: je past de methode .describe() toe op elke groep in de groupby. Doe dit en print de eerste 5 rijen van het resultaat:
Als je wilt zien hoe de groepering eruitziet, kun je het groupby-object doorgeven aan de functie list():
# Cast grouping as a list and check out one yearlist(df_by_year)[10]Mogelijk gemaakt door
(1995, title rating ratinglevel \
766 Balto G General Audiences. Suitable for all ages.967 Heavyweights PG some rude language and pranks
ratingdescription release_year user_rating_score user_rating_size
76635199564.08096760199574.080)Mogelijk gemaakt door
Stap 3. Combine
Stel dat je de gemiddelde of mediane user_rating_score per jaar wilt. Dan kun je respectievelijk de methode .mean() of .median() toepassen op het groupby-object en deze 'combineren' tot een nieuwe DataFrame.
# Get median values by year and print first 5 rows
df_med_by_year = df_by_year.median()
df_med_by_year.head()Mogelijk gemaakt door
ratingdescription
user_rating_score
user_rating_size
release_year
1940
35.0
61.0
80.0
1978
60.0
86.0
80.0
1982
60.0
68.0
80.0
1986
35.0
67.0
80.0
1987
60.0
58.0
80.0
Er is een belangrijk subtiliteit met betrekking tot de index van de DataFrame df_med_by_year. Denk eraan dat de index van een DataFrame uit de rijlijnen bestaat. Bekijk de index van de oorspronkelijke DataFrame df:
Int64Index([0,2,3,4,5,6,7,8,9,10,...908,911,917,931,962,966,967,972,973,979],
dtype='int64', length=246)Mogelijk gemaakt door
Deze index bestaat uit de oorspronkelijke rijnummers, gelabeld met gehele getallen. '1' ontbreekt omdat je hierboven enkele rijen hebt gedropt. De index van df_med_by_year bestaat uit de waarden in de oorspronkelijke kolom waarop je hebt gegroepeerd, de jaren uit release_year:
Int64Index([1940,1978,1982,1986,1987,1989,1990,1992,1993,1994,1995,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017],
dtype='int64', name='release_year')Mogelijk gemaakt door
Je bent geïnteresseerd in de kolom user_rating_score, die de mediane beoordeling per jaar bevat. Je kunt de kolom user_rating_score uit df_med_by_year slicen en deze plotten als functie van het jaar (gegeven door de index van de DataFrame df_rat_by_year):
# Slice out user rating and plot
df_rat_by_year = df_med_by_year['user_rating_score']
plt.scatter(df_rat_by_year.index, df_rat_by_year)
plt.xlabel('year of release')
plt.ylabel('median rating');Mogelijk gemaakt door
Kijkend naar de figuur neemt de mediane beoordeling duidelijk toe in de tijd. Je zou meer geavanceerde statistiek nodig hebben om me in het algemeen van de trend te overtuigen, maar dit is een voorbeeld van Exploratory Data Analysis als uitstekend startpunt voor verder onderzoek.
Groupbys en split-apply-combine in het dagelijks gebruik
Groupby-objecten zijn niet intuïtief. Ze komen echter overeen met de natuurlijke handeling om een dataset te splitsen ten opzichte van een van de kolommen (of meer dan één, maar dat bewaren we voor een andere post over groeperen op meerdere kolommen en hiërarchische indexen).
Het split-apply-combine-principe is niet alleen elegant en praktisch, het is iets wat Data Scientists dagelijks gebruiken, zoals in het bovenstaande voorbeeld. Om meer van de toepassingen te waarderen, bekijk Hadley Wickham's oorspronkelijke paperThe Split-Apply-Combine Strategy for Data Analysis. Als je gedachten, reacties en/of overpeinzingen hebt, neem gerust contact op met me op Twitter: @hugobowne.
Bekijk ook DataCamp's andere handige pandas-tutorials, waaronder:
Netflix heeft onlangs gebruikersbeoordelingen vrijgegeven. Ik wilde een eenvoudige vraag stellen: geven Netflix-abonnees de voorkeur aan oudere of nieuwere films?
Intuïtief wil je de dataset opsplitsen in groepen, één voor elk jaar, vervolgens een samenvattende statistiek berekenen, zoals het gemiddelde of de mediaan, en dan kijken of deze statistiek over de jaren toeneemt (daarna wil je misschien een statistische toets uitvoeren).
Het mooie is dat er een conceptueel kader voor bestaat, met implementaties in zowel Python als R. Dit kader staat bekend als "split-apply-combine" omdat we...
Dit is het conceptuele kader voor de analyse die we gaan doen. In deze post leer je hoe je dit toepast om de Netflix-vraag hierboven te beantwoorden met behulp van het Python-pakket
pandas. Je kunt hetzelfde in R doen met bijvoorbeeld het pakketdplyr. Ik ga ook noodgedwongen in op groupby-objecten, die niet de meest intuïtieve objecten zijn. Het split-apply-combine-proces met groupby-objecten is een patroon dat we allemaal intuïtief uitvoeren, zoals we zullen zien, maar het was Hadley Wickham die de procedure in 2011 formaliseerde met zijn paper The Split-Apply-Combine Strategy for Data Analysis.Als je deze techniek handig vindt, kun je er (naast veel andere zaken) meer over leren en ermee oefenen in onze cursus Manipulating DataFrames with pandas.
Data verkennen met pandas
Importeer je data
Hier gebruik je
pandas, groupby-objecten en de principes van split-apply-combine om te bekijken hoe de Netflix-filmscores variëren als functie van het jaar waarin ze zijn uitgebracht. Ik kwam de data oorspronkelijk tegen op data.world hier. Je vindt alle code in deze post hier als je het wilt reproduceren.Je importeert eerst de benodigde pakketten en de data en bekijkt de eerste vijf rijen van de data:
Dit ziet er prima uit: je hebt titels, classificaties, uitbrengjaar en gebruikersscore, naast diverse andere kolommen. Voordat we onze groupby- en split-apply-combine-procedure uitvoeren, kijken we iets nauwkeuriger naar de data om zeker te weten dat die is wat we denken en om met missende waarden om te gaan. Merk op dat er een missende waarde NaN staat in de user_rating_score van de tweede rij (rij 1).
Je data samenvatten met grafieken en statistieken
De
pandasDataFrame-methode.info()is onmisbaar. Toepassen hieronder laat zien dat je 1000 rijen en 7 kolommen hebt, maar ook dat de kolom van belang, user_rating_score, slechts 605 niet-lege waarden heeft. Dit betekent dat er 395 missende waarden zijn:Je kunt rijen met missende waarden droppen, dubbele rijen verwijderen en een pairplot van de DataFrame maken met
seabornom een visueel gevoel voor de data te krijgen. Je kleurt de data op basis van de kolom 'rating'. Bekijk de grafieken en kijk welke informatie je eruit haalt.Bekijk bijvoorbeeld user_rating_score als functie van release_year. Er is geen visueel duidelijke trend, maar wellicht brengt wat data-analyse trends naar voren. Als je verschillende samenvattende statistieken van de DataFrame wilt bekijken, kan dat ook met de methode
.describe():Groupbys en split-apply-combine om de vraag te beantwoorden
Stap 1. Split
Nu je de data hebt verkend, is het tijd voor het leuke gedeelte. Je gebruikt eerst een groupby-methode om de data op te splitsen in groepen, waarbij elke groep de set films is die in een bepaald jaar zijn uitgebracht. Dit is de split in split-apply-combine:
Dit creëert een groupby-object:
Stap 2. Apply
Dergelijke groupby-objecten zijn erg nuttig. Weet je nog dat de methode
.describe()voor een DataFrame samenvattende statistieken voor numerieke kolommen teruggeeft? Welnu, de methode.describe()voorDataFrameGroupBy-objecten geeft samenvattende statistieken voor elke numerieke kolom, maar dan per groep in de split. In jouw geval is dat per release_year. Dit is een voorbeeld van de apply in split-apply-combine: je past de methode.describe()toe op elke groep in de groupby. Doe dit en print de eerste 5 rijen van het resultaat:5 rows × 24 columns
Als je wilt zien hoe de groepering eruitziet, kun je het groupby-object doorgeven aan de functie
list():Stap 3. Combine
Stel dat je de gemiddelde of mediane user_rating_score per jaar wilt. Dan kun je respectievelijk de methode
.mean()of.median()toepassen op het groupby-object en deze 'combineren' tot een nieuwe DataFrame.Er is een belangrijk subtiliteit met betrekking tot de index van de DataFrame
df_med_by_year. Denk eraan dat de index van een DataFrame uit de rijlijnen bestaat. Bekijk de index van de oorspronkelijke DataFramedf:Deze index bestaat uit de oorspronkelijke rijnummers, gelabeld met gehele getallen. '1' ontbreekt omdat je hierboven enkele rijen hebt gedropt. De index van
df_med_by_yearbestaat uit de waarden in de oorspronkelijke kolom waarop je hebt gegroepeerd, de jaren uit release_year:Je bent geïnteresseerd in de kolom user_rating_score, die de mediane beoordeling per jaar bevat. Je kunt de kolom user_rating_score uit
df_med_by_yearslicen en deze plotten als functie van het jaar (gegeven door de index van de DataFramedf_rat_by_year):Kijkend naar de figuur neemt de mediane beoordeling duidelijk toe in de tijd. Je zou meer geavanceerde statistiek nodig hebben om me in het algemeen van de trend te overtuigen, maar dit is een voorbeeld van Exploratory Data Analysis als uitstekend startpunt voor verder onderzoek.
Groupbys en split-apply-combine in het dagelijks gebruik
Groupby-objecten zijn niet intuïtief. Ze komen echter overeen met de natuurlijke handeling om een dataset te splitsen ten opzichte van een van de kolommen (of meer dan één, maar dat bewaren we voor een andere post over groeperen op meerdere kolommen en hiërarchische indexen).
Het split-apply-combine-principe is niet alleen elegant en praktisch, het is iets wat Data Scientists dagelijks gebruiken, zoals in het bovenstaande voorbeeld. Om meer van de toepassingen te waarderen, bekijk Hadley Wickham's oorspronkelijke paper The Split-Apply-Combine Strategy for Data Analysis. Als je gedachten, reacties en/of overpeinzingen hebt, neem gerust contact op met me op Twitter: @hugobowne.
Bekijk ook DataCamp's andere handige pandas-tutorials, waaronder: