Kolommen
Contents
2.3. Kolommen#
In dit hoofdstukje behandelen we een paar operaties die op de kolommen van een DataFrame van toepassing zijn.
2.3.1. Typen kolommen#
Bij het aanmaken van een DataFrame zelf, of een nieuwe kolom in een bestaand DataFrame, probeert pandas al te kijken welk type variabele er in een kolom staat. Als we ons eerste voorbeeld bekijken:
import pandas as pd
# We schrijven een 'dict' met alle informatie:
invoer = {'Naam': ['Pietje', 'Greetje', 'Daan'], 'Leeftijd': [23, 22, 25]}
# Vervolgens converteren we deze 'dict' naar een DataFrame object:
data = pd.DataFrame(invoer)
print(data['Naam'])
print(data['Leeftijd'])
0 Pietje
1 Greetje
2 Daan
Name: Naam, dtype: object
0 23
1 22
2 25
Name: Leeftijd, dtype: int64
dan kunnen we al zien dat pandas al wel herkend heeft dat de leeftijds-kolom alleen getallen bevat: het datatype (dtype) is een soort int. Maar van de kolom die de namen bevat, is het datatype geen str, maar blijkbaar object. Met zo’n object kunnen we wat trucjes uitvoeren. De belangrijkste daarvan is, dat we kunnen opvragen of er een specifieke tekst in de dataset zit:
filter_greetje = data['Naam'].str.contains('Greetje')
print(filter_greetje)
0 False
1 True
2 False
Name: Naam, dtype: bool
Dit is handig als we data willen filteren, met als voorwaarde dat er een bepaalde tekst in een kolom staat.
Voor de kolommen met een getal erin heb je al eerder gezien dat we direct een wiskundige operatie op de hele kolom kunnen toepassen. Daarover lees je meer in het volgende blokje.
2.3.2. Een nieuwe kolom maken#
Je kunt eenvoudig een nieuwe kolom aanmaken door een stukje code als hieronder. Merk op dat we meteen een wiskundige operatie op de hele kolom kunnen toepassen (delen door twee, kwadraat en keer \(\pi\)), zonder dat we iets als een for-loop nodig hebben.
De syntax om een nieuwe kolom aan te maken is vergelijkbaar als het opvragen van een bestaande kolom, alleen nu staat er data['nieuwe_kolom'] links van het = -teken.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
naam = ['M4', 'M6', 'M8', 'M10', 'M12']
diameter = [4, 6, 8, 10, 12]
invoer = {'Naam': naam, 'Diameter': diameter}
data = pd.DataFrame(invoer)
# Maak een nieuwe kolom aan, waarbij we het
# oppervlak van een dwarsdoorsnede berekenen.
data['Oppervlak'] = (data['Diameter'] / 2) ** 2 * np.pi
print(data)
plt.plot(data['Naam'], data['Oppervlak'])
plt.grid()
plt.xlabel('Soort boutje')
plt.ylabel('Oppervlakte dwarsdoorsnede (mm²)')
plt.show()
Naam Diameter Oppervlak
0 M4 4 12.566371
1 M6 6 28.274334
2 M8 8 50.265482
3 M10 10 78.539816
4 M12 12 113.097336
Let er wel op dat je nieuwe kolom evenveel rijen bevat als het originele DataFrame. De foutmelding is niet heel vriendelijk, maar als het goed is kun je onderaan nog lezen dat we niet genoeg waarden meegeven aan de nieuwe kolom.
naam = ['M6', 'M8', 'M10', 'M12']
diameter = [6, 8, 10, 12]
invoer = {'Naam': naam, 'Diameter': diameter}
data = pd.DataFrame(invoer)
# Maak een nieuwe kolom aan, waarbij we het
# oppervlak van een dwarsdoorsnede handmatig invoeren.
data['Oppervlak'] = [28.3, 50.3, 78.5]
print(data)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-2cfc8ac89bc2> in <cell line: 9>()
7 # Maak een nieuwe kolom aan, waarbij we het
8 # oppervlak van een dwarsdoorsnede handmatig invoeren.
----> 9 data['Oppervlak'] = [28.3, 50.3, 78.5]
10
11 print(data)
~/.local/lib/python3.8/site-packages/pandas/core/frame.py in __setitem__(self, key, value)
3042 else:
3043 # set column
-> 3044 self._set_item(key, value)
3045
3046 def _setitem_slice(self, key: slice, value):
~/.local/lib/python3.8/site-packages/pandas/core/frame.py in _set_item(self, key, value)
3118 """
3119 self._ensure_valid_index(value)
-> 3120 value = self._sanitize_column(key, value)
3121 NDFrame._set_item(self, key, value)
3122
~/.local/lib/python3.8/site-packages/pandas/core/frame.py in _sanitize_column(self, key, value, broadcast)
3766
3767 # turn me into an ndarray
-> 3768 value = sanitize_index(value, self.index)
3769 if not isinstance(value, (np.ndarray, Index)):
3770 if isinstance(value, list) and len(value) > 0:
~/.local/lib/python3.8/site-packages/pandas/core/internals/construction.py in sanitize_index(data, index)
745 """
746 if len(data) != len(index):
--> 747 raise ValueError(
748 "Length of values "
749 f"({len(data)}) "
ValueError: Length of values (3) does not match length of index (4)