{count, plural, one {Cursus} other {Cursussen}}
Inleiding
Data importeren is een van de belangrijkste en allereerste stappen bij elk dataprobleem. De vaardigheid om data correct te importeren is onmisbaar voor elke beginnende data scientist.
Data bestaat in veel verschillende vormen. Je moet niet alleen weten hoe je uiteenlopende dataformaten importeert, maar ook hoe je de data analyseert en bewerkt om bruikbare inzichten te krijgen.
pandas is een open-source Python-bibliotheek die makkelijk te gebruiken is, hoge prestaties levert en een analyse-tool biedt voor diverse dataformaten.
Het geeft je de mogelijkheid om verschillende soorten dataformaten te lezen, zoals CSV, JSON, Excel, Pickle, enz. Het laat je data weergeven in een tabel met rijen en kolommen, wat de data leesbaar en presenteerbaar maakt.
pandas stelt de data voor in een DataFrame en biedt uitgebreide mogelijkheden voor data-analyse en -manipulatie. Zodra je met de verschillende functionaliteiten in pandas grip krijgt op de data, kun je deze gegevens gebruiken voor analyseren, voorspellen, classificeren en meer!
pandas heeft een input- en output-API met een set top-level reader- en writer-functies. De reader-functie is toegankelijk via pandas.read_json() en retourneert een pandas-object, en de writer-functie is toegankelijk via pandas.to_json(), een objectmethode.
DataFrame heeft een Reader- en een Writer-functie. Met de Reader-functie lees je verschillende dataformaten, terwijl de Writer-functie je in staat stelt om de data in een bepaald formaat op te slaan.
Hieronder staan dataformaten die DataFrame ondersteunt. Dat betekent dat als jouw data in een van de onderstaande vormen staat, je pandas kunt gebruiken om dat formaat te laden en zelfs in een specifiek formaat weg te schrijven.
In de tutorial van vandaag ga je werken met een paar van de bovenstaande typen, zoals JSON, HTML en Pickle.
Opmerking: Bekijk deze tutorial om te leren hoe je CSV-bestanden leest met pandas.
JSON-gegevens laden
JSON, ook bekend als JavaScript Object Notation, is een tekstserialisatieformaat voor gegevensuitwisseling. JSON is makkelijk te lezen en te schrijven. Het is gebaseerd op een subset van de programmeertaal JavaScript, maar gebruikt conventies uit Python en vele andere talen buiten Python.
JSON wordt meestal gebruikt om ongestructureerde data op te slaan, en SQL-databases hebben er moeite mee om dit op te slaan. JSON maakt de data toegankelijk om door machines gelezen te worden.
JSON is vooral gebaseerd op twee structuren:
-
Een collectie van key/value-paren. In Python noem je een key/value-paar een
Dictionary, waarbij eenkeyeen uniek attribuut is en waarden dat niet per se zijn. -
Een geordende lijst met waarden. De geordende lijst kan soms ook een lijst van lijsten zijn. Lijsten in Python zijn een reeks waarden die een string, integer, enz. kunnen zijn.
Laten we nu bekijken hoe je de JSON-data op meerdere manieren kunt laden.
De eerste JSON-dataset komt van deze link. De data staat in een key-value dictionary-formaat. Er zijn in totaal drie keys: namelijk integer, datetime en category.
- Je importeert eerst de
pandas-bibliotheek en geeft vervolgens deURLdoor aanpd.read_json(), wat een dataframe retourneert. De kolommen van het dataframe vertegenwoordigen de keys en de rijen zijn de waarden van de JSON.
import pandas as pd
json = pd.read_json('https://raw.githubusercontent.com/chrisalbon/simulated_datasets/master/data.json')
Laten we snel de laatste paar rijen van de JSON die je hebt gelezen afdrukken met de functie .tail().
json.tail(6)
| integer | datetime | category | |
|---|---|---|---|
| 94 | 5 | 2015-01-01 00:01:34 | 0 |
| 95 | 9 | 2015-01-01 00:01:35 | 0 |
| 96 | 8 | 2015-01-01 00:01:36 | 0 |
| 97 | 6 | 2015-01-01 00:01:37 | 0 |
| 98 | 8 | 2015-01-01 00:01:38 | 0 |
| 99 | 1 | 2015-01-01 00:01:39 | 0 |
json.shape
(100, 3)
Uit de bovenstaande output zie je dat er in totaal drie kolommen zijn: integer, datetime en category. Ook zijn er 100 voorbeelden in de dataset, zoals bevestigd door de methode .shape, die een 100 x 3-output teruggaf.
- JSON wegschrijven
Het wegschrijven van JSON-data is net zo eenvoudig als het lezen en kost één regel code. In plaats van read_json() gebruik je to_json() met een bestandsnaam en dat is alles!
json.to_json('dataframe.json')
- Geneste JSON als string parsen
Vervolgens gebruik je een ander type JSON-dataset, die niet zo eenvoudig is. Het is een geneste JSON-structuur. Een geneste JSON-structuur betekent dat elke key meer bijbehorende keys kan hebben.
Laten we de voorbeeld-dataset bekijken om het beter te begrijpen.
nested_json = """{
"article": [
{
"id":"01",
"language": "JSON",
"edition": "first",
"author": "Allen"
},
{
"id":"02",
"language": "Python",
"edition": "second",
"author": "Aditya Sharma"
}
],
"blog":[
{
"name": "Datacamp",
"URL":"datacamp.com"
}
]
}"""
In de bovenstaande dataset zie je dat article en blog twee primaire keys zijn waaronder de waarden van deze keys vallen. Deze waarden hebben hun eigen combinatie van key-value-paren.
Let op dat de bovenstaande dataset is ingesloten met aanhalingstekens en de vorm heeft van een string.
Een geneste JSON lezen kan op meerdere manieren.
Eerst gebruik je de functie json.loads om een JSON-string te lezen door de datavariabele als parameter door te geven. Daarna gebruik je de functie json_normalize om de geneste JSON-data af te vlakken naar een tabel.
Je importeert de functie json_normalize uit de bibliotheek pandas.io.json.
import json
from pandas.io.json import json_normalize
nested = json.loads(nested_json)
nested
{'article': [{'id': '01',
'language': 'JSON',
'edition': 'first',
'author': 'Allen'},
{'id': '02',
'language': 'Python',
'edition': 'second',
'author': 'Aditya Sharma'}],
'blog': [{'name': 'Datacamp', 'URL': 'datacamp.com'}]}
Vervolgens ga je de JSON afvlakken met de normalize-functie. Je geeft voor nu de volledige data door om te zien hoe dat eruitziet.
nested_full = json_normalize(nested)
nested_full
| article | blog | |
|---|---|---|
| 0 | [{'id': '01', 'language': 'JSON', 'edition': '... | [{'name': 'Datacamp', 'URL': 'datacamp.com'}] |
Mooi! Zoals je in de bovenstaande output ziet, zijn de primaire keys de kolommen van het dataframe terwijl de keys de rij voorstellen.
De output oogt echter wat rommelig, toch? Laten we kijken hoe je dit verder kunt opsplitsen in meerdere dataframes.
Je geeft opnieuw de output van json.loads door aan json_normalize, maar dit keer specificeer je een extra element genaamd record_path.
blog = json_normalize(nested,record_path ='blog')
blog
| URL | name | |
|---|---|---|
| 0 | datacamp.com | Datacamp |
article = json_normalize(nested,record_path ='article')
article
| author | edition | id | language | |
|---|---|---|---|---|
| 0 | Allen | first | 01 | JSON |
| 1 | Aditya Sharma | second | 02 | Python |
Uit de bovenstaande outputs zie je dat de primaire keys nu zijn opgesplitst in twee verschillende dataframes, waarbij de kolomnamen nu de keys zijn die genest waren binnen de primaire keys als key-valuepaar. Mooi, toch?
Tot slot, om het laden van JSON-gegevens af te ronden, kijken we snel hoe je JSON als bestand kunt lezen in plaats van als string.
- JSON als bestand lezen
nested_json = {
"article": [
{
"id":"01",
"language": "JSON",
"edition": "first",
"author": "Allen"
},
{
"id":"02",
"language": "Python",
"edition": "second",
"author": "Aditya Sharma"
}
],
"blog":[
{
"name": "Datacamp",
"URL":"datacamp.com"
}
]
}
Als je goed kijkt in de bovenstaande cel, staan er geen aanhalingstekens aan het begin en einde van de data. Dat betekent dat je deze data als bestand zult behandelen en inlezen.
Dit kun je bereiken met slechts één regel code. Laten we zien hoe!
json_file = pd.DataFrame.from_dict(json_normalize(nested_json))
json_file
| article | blog | |
|---|---|---|
| 0 | [{'id': '01', 'language': 'JSON', 'edition': '... | [{'name': 'Datacamp', 'URL': 'datacamp.com'}] |
Uit de bovenstaande output zie je dat de output vergelijkbaar is met wanneer je JSON als string las. Het enige verschil hier is dat je pandas gebruikt om zowel te parsen als af te vlakken. Omdat de JSON een dictionary is, gebruik je de functie .from_dict().
HTML-gegevens laden
HTML is een Hypertext Markup Language die vooral wordt gebruikt voor het maken van webapplicaties en -pagina's. Het probeert de structuur van de webpagina semantisch te beschrijven. De webbrowser ontvangt een HTML-document van een webserver en rendert dit naar een multimediale webpagina.
Voor webapplicaties wordt HTML gebruikt met cascading style sheets (CSS), terwijl het aan de serverkant samenwerkt met verschillende webserver-frameworks zoals Flask, Django, enz.
HTML gebruikt tags om elk codeblok te definiëren, zoals een <p></p>-tag voor het begin en einde van een alinea, een <image></image>-tag om content als afbeelding toe te voegen aan de webpagina, en zo zijn er veel tags die samen een HTML-webpagina vormen.
Om een HTML-bestand te lezen, zoekt een pandas-dataframe naar een tag. Die tag is een <td></td>-tag. Deze tag wordt gebruikt om een tabel in HTML te definiëren.
pandas gebruikt read_html() om het HTML-document te lezen.
Dus wanneer je een HTML aan pandas doorgeeft en een netjes dataframe verwacht, zorg er dan voor dat de HTML-pagina een tabel bevat!
- Over de data: je gebruikt een
Cryptocurrency-website als HTML-dataset die verschillende cryptomunten bevat en diverse details per munt, zoals:- Laatste prijs van de munt (
Last price) - Of de prijs is gestegen of gedaald (in percentage
%) - Het volume over 24 uur (hoeveel munten zijn verhandeld
24 volume) - Totaal aantal munten (
# Coins)
- Laatste prijs van de munt (
Dus, aan de slag!
Je importeert eerst de bibliotheek requests, die je helpt om een verzoek te sturen naar de URL waarvan je de HTML-content wilt ophalen.
import requests
url = 'https://www.worldcoinindex.com/'
crypto_url = requests.get(url)
crypto_url
<Response [200]>
Tot nu toe heb je de URL gedefinieerd en vervolgens met requests.get() een verzoek naar die URL gestuurd en een response ontvangen als een acknowledgement [200] OK, wat betekent dat je verbinding kon maken met die webserver.
Om de inhoud van de HTML-webpagina te lezen, hoef je nu alleen maar crypto_url.text aan te roepen. Dat geeft je de HTML-code van die cryptocurrency-webpagina.
Voel je vrij om het commando crypto_url.text uit te voeren om de output te zien.
Tot slot geef je crypto_url.text door aan de functie pd.read_html(), die je een lijst met dataframes retourneert, waarbij elk element in die lijst een tabel (dataframe) is die de cryptocurrency-webpagina bevat.
crypto_data = pd.read_html(crypto_url.text)
Laten we de lengte en het type van het dataframe afdrukken. Het type zou een list moeten zijn.
len(crypto_data), type(crypto_data)
(1, list)
Uit de bovenstaande output blijkt dat er slechts 1 tabel is met type list.
crypto_data = crypto_data[0]
Laten we de eerste en tweede kolom verwijderen, omdat die geen nuttige informatie bevatten, en alle rijen behouden.
crypto_final = crypto_data.iloc[:,2:]
Nu is het tijd om het cryptocurrency-dataframe af te drukken!
crypto_final.head()
| Name | Ticker | Last price | % | 24 high | 24 low | Price Charts 7d | 24 volume | # Coins | Market cap | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | bitcoin | BTC | $ 8,008.027 | +1.83% | $ 8,056.630 | $ 7,812.784 | NaN | $ 12.04B | 17.71M | $ 141.89B |
| 1 | ethereum | ETH | $ 251.72335 | +2.68% | $ 253.84721 | $ 242.95687 | NaN | $ 6.93B | 106.20M | $ 26.73B |
| 2 | litecoin | LTC | $ 98.633851 | +11.08% | $ 99.946324 | $ 88.618815 | NaN | $ 3.46B | 61.91M | $ 6.10B |
| 3 | bitcoincash | BCH | $ 411.94075 | +2.31% | $ 418.60850 | $ 394.18927 | NaN | $ 2.10B | 17.79M | $ 7.33B |
| 4 | eos | EOS | $ 6.4230717 | +6.05% | $ 6.4765695 | $ 6.0264079 | NaN | $ 2.06B | 1.01B | $ 6.50B |
Uit de bovenstaande tabel kun je opmerken dat Bitcoin de meeste Market Cap heeft.
NaN (Not a Number) verwijderen
Er staan enkele waarden in het dataframe die geen echte waarden zijn, dus laten we die snel uit de tabel verwijderen.
We laten eerst de kolom Price Charts 7d volledig vallen (verwijderen), omdat die volledig NaN is en geen informatie bevat.
del crypto_final['Price Charts 7d']
crypto_final.head()
| Name | Ticker | Last price | % | 24 high | 24 low | 24 volume | # Coins | Market cap | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | bitcoin | BTC | $ 8,008.027 | +1.83% | $ 8,056.630 | $ 7,812.784 | $ 12.04B | 17.71M | $ 141.89B |
| 1 | ethereum | ETH | $ 251.72335 | +2.68% | $ 253.84721 | $ 242.95687 | $ 6.93B | 106.20M | $ 26.73B |
| 2 | litecoin | LTC | $ 98.633851 | +11.08% | $ 99.946324 | $ 88.618815 | $ 3.46B | 61.91M | $ 6.10B |
| 3 | bitcoincash | BCH | $ 411.94075 | +2.31% | $ 418.60850 | $ 394.18927 | $ 2.10B | 17.79M | $ 7.33B |
| 4 | eos | EOS | $ 6.4230717 | +6.05% | $ 6.4765695 | $ 6.0264079 | $ 2.06B | 1.01B | $ 6.50B |
Laat we nu de NaN's verwijderen.
crypto_final = crypto_final.dropna()
De cryptomunten visualiseren (Ticker) versus procentuele stijging/daling in prijs (%)
Laten we eerst matplotlib importeren om de grafiek te plotten.
import matplotlib.pyplot as plt
%matplotlib inline
De kolom % heeft het type string en je moet dit type string omzetten naar float. Eerst verwijder je het %-teken uit de kolom en vervolgens zet je het type van de kolom % om naar float.
crypto_final['%'] = crypto_final['%'].apply(lambda x: x.strip('%'))
crypto_final['%'] = crypto_final['%'].astype('float')
Laten we nu de data plotten.
plt.figure()
plt.figure(figsize=(16,10))
x = crypto_final.iloc[:20]['Ticker']
y = crypto_final.iloc[:20]['%']
plt.xticks(fontsize=12)
plt.yticks(fontsize=14)
plt.xlabel('Percentage Increase/Decrease in Price',fontsize=20)
plt.ylabel('Ticker',fontsize=20)
plt.plot(x,y,label='% Increase/Decrease in Price')
plt.legend(loc='lower left',prop={'size': 15})
<matplotlib.legend.Legend at 0x1298a9630>
<Figure size 432x288 with 0 Axes>
Uit de bovenstaande grafiek kun je opmerken dat de Litecoin (LTC) en Huobitoken (HT) de grootste prijsstijging hebben en dat Maticnetwork (MATIC) en Waves de grootste prijsdaling van de cryptomunten laten zien.
Pickle-gegevens laden
Pickle is een Python-specifiek binair serialisatieformaat dat, in tegenstelling tot JSON, niet door mensen leesbaar is. Het wordt gebruikt voor het serialiseren en deserialiseren van een Python-objectstructuur. Het serialiseert het object en "pickled" het om op schijf op te slaan. Het zet het object, zoals DataFrame, lijst, dictionary, enz., om in een tekenstroom.
Het grootste voordeel van Pickle is dat het verschillende soorten Python-datatypen kan opslaan.
Pickle wordt veel gebruikt voor het opslaan van getrainde machine learning-algoritme-instanties. Net als JSON heeft Pickle handige functies zoals pickle.load() voor het laden van een Pickle-bestand en pickle.dump() voor het opslaan van een Pickle of elk ander formaat in Pickle-formaat.
Een ander belangrijk voordeel van Pickle is dat het opslaan van het dataframe als Pickle-bestand minder schijfruimte vereist en het type van de data intact blijft bij het opnieuw laden.
Laten we dus snel het eerder geconstrueerde cryptocurrency-dataframe picklen, en daarna lees je dat gepicklede object in met pandas.
import pickle
Je gebruikt pickle.dump om het dataframe als Pickle-object op te slaan en gebruikt protocol als HIGHEST_PROTOCOL, wat ook achterwaarts compatibel is met Python 2.
with open('crypto_final.pickle', 'wb') as sub_data:
pickle.dump(crypto_final, sub_data, protocol=pickle.HIGHEST_PROTOCOL)
Tot slot gebruik je de pandas-functie read_pickle om het pickle-object om te zetten in een dataframe.
crypto_final = pd.read_pickle('crypto_final.pickle')
crypto_final.head()
| Name | Ticker | Last price | % | 24 high | 24 low | 24 volume | # Coins | Market cap | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | bitcoin | BTC | $ 7,776.567 | +1.81% | $ 7,870.205 | $ 7,506.518 | $ 12.70B | 17.71M | $ 137.78B |
| 1 | ethereum | ETH | $ 241.81372 | -0.97% | $ 245.57293 | $ 232.62523 | $ 7.47B | 106.18M | $ 25.67B |
| 2 | litecoin | LTC | $ 88.062811 | +0.33% | $ 88.946501 | $ 85.248641 | $ 2.59B | 61.90M | $ 5.45B |
| 3 | bitcoincash | BCH | $ 388.76089 | +0.06% | $ 398.27697 | $ 370.29831 | $ 2.33B | 17.79M | $ 6.91B |
| 4 | eos | EOS | $ 5.9327948 | -0.41% | $ 6.0163442 | $ 5.7789154 | $ 1.99B | 1.01B | $ 6.00B |
Wauw! Is dat niet geweldig? Zo eenvoudig was het. Bovendien hoef je je met Pickle geen zorgen te maken over fouten bij het converteren van datatypen, omdat de pickle-serialisatie dat voor je kan afhandelen!
Ga verder
Gefeliciteerd met het afronden van de tutorial.
Deze tutorial was een goed startpunt om te leren hoe je verschillende dataformaten in Python kunt laden met behulp van pandas.
Er zijn nog veel meer dataformaten zoals Excel, SQL, HDF5, enz. die onder de pandas-paraplu voor data-import vallen. Je zou hiermee aan de slag moeten gaan door interessante publieke datasets in deze formaten te vinden en ermee te experimenteren.
Wil je meer leren over DataFrames in pandas? Volg de interactieve cursus data manipulation with pandas van DataCamp. DataCamp heeft ook verschillende andere handige pandas-tutorials over dataframes samenvoegen, voortschrijdende gemiddelden implementeren en de apply-methode gebruiken. Of, als je helemaal nieuw bent met pandas, begin dan met deze beginnersgids voor pandas.
Referenties:
Stel gerust vragen over deze tutorial in de reacties hieronder.
