pandas
Gegevens indexeren en selecteren
Zoeken…
Selecteer kolom op label
# Create a sample DF
df = pd.DataFrame(np.random.randn(5, 3), columns=list('ABC'))
# Show DF
df
A B C
0 -0.467542 0.469146 -0.861848
1 -0.823205 -0.167087 -0.759942
2 -1.508202 1.361894 -0.166701
3 0.394143 -0.287349 -0.978102
4 -0.160431 1.054736 -0.785250
# Select column using a single label, 'A'
df['A']
0 -0.467542
1 -0.823205
2 -1.508202
3 0.394143
4 -0.160431
# Select multiple columns using an array of labels, ['A', 'C']
df[['A', 'C']]
A C
0 -0.467542 -0.861848
1 -0.823205 -0.759942
2 -1.508202 -0.166701
3 0.394143 -0.978102
4 -0.160431 -0.785250
Aanvullende informatie op: http://pandas.pydata.org/pandas-docs/version/0.18.0/indexing.html#selection-by-label
Selecteer op positie
Met de iloc
( iloc
voor gehele locatie ) kunt u de rijen van een dataframe selecteren op basis van hun positie-index. Op deze manier kun je dataframes segmenteren, net zoals je doet met Pythons list slicing.
df = pd.DataFrame([[11, 22], [33, 44], [55, 66]], index=list("abc"))
df
# Out:
# 0 1
# a 11 22
# b 33 44
# c 55 66
df.iloc[0] # the 0th index (row)
# Out:
# 0 11
# 1 22
# Name: a, dtype: int64
df.iloc[1] # the 1st index (row)
# Out:
# 0 33
# 1 44
# Name: b, dtype: int64
df.iloc[:2] # the first 2 rows
# 0 1
# a 11 22
# b 33 44
df[::-1] # reverse order of rows
# 0 1
# c 55 66
# b 33 44
# a 11 22
Rijlocatie kan worden gecombineerd met kolomlocatie
df.iloc[:, 1] # the 1st column
# Out[15]:
# a 22
# b 44
# c 66
# Name: 1, dtype: int64
Zie ook: Selectie op positie
Snijden met labels
Bij het gebruik van labels worden zowel de start als de stop opgenomen in de resultaten.
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
# Out:
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
# R2 7 76 15 53 80
# R3 27 44 77 75 65
# R4 47 30 84 86 18
Rijen R0
tot R2
:
df.loc['R0':'R2']
# Out:
# A B C D E
# R0 9 41 62 1 82
# R1 16 78 5 58 0
# R2 80 4 36 51 27
Merk op hoe loc
verschilt van iloc
omdat iloc
de iloc
uitsluit
df.loc['R0':'R2'] # rows labelled R0, R1, R2
# Out:
# A B C D E
# R0 9 41 62 1 82
# R1 16 78 5 58 0
# R2 80 4 36 51 27
# df.iloc[0:2] # rows indexed by 0, 1
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
Kolommen C
tot E
:
df.loc[:, 'C':'E']
# Out:
# C D E
# R0 62 1 82
# R1 5 58 0
# R2 36 51 27
# R3 68 38 83
# R4 7 30 62
Gemengde positie en op labels gebaseerde selectie
dataframe:
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
df
Out[12]:
A B C D E
R0 99 78 61 16 73
R1 8 62 27 30 80
R2 7 76 15 53 80
R3 27 44 77 75 65
R4 47 30 84 86 18
Selecteer rijen op positie en kolommen op label:
df.ix[1:3, 'C':'E']
Out[19]:
C D E
R1 5 58 0
R2 36 51 27
Als de index een geheel getal is, gebruikt .ix
labels in plaats van posities:
df.index = np.arange(5, 10)
df
Out[22]:
A B C D E
5 9 41 62 1 82
6 16 78 5 58 0
7 80 4 36 51 27
8 31 2 68 38 83
9 19 18 7 30 62
#same call returns an empty DataFrame because now the index is integer
df.ix[1:3, 'C':'E']
Out[24]:
Empty DataFrame
Columns: [C, D, E]
Index: []
Booleaanse indexering
Men kan rijen en kolommen van een dataframe selecteren met behulp van Booleaanse arrays.
import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(5, 5)), columns = list("ABCDE"),
index = ["R" + str(i) for i in range(5)])
print (df)
# A B C D E
# R0 99 78 61 16 73
# R1 8 62 27 30 80
# R2 7 76 15 53 80
# R3 27 44 77 75 65
# R4 47 30 84 86 18
mask = df['A'] > 10
print (mask)
# R0 True
# R1 False
# R2 False
# R3 True
# R4 True
# Name: A, dtype: bool
print (df[mask])
# A B C D E
# R0 99 78 61 16 73
# R3 27 44 77 75 65
# R4 47 30 84 86 18
print (df.ix[mask, 'C'])
# R0 61
# R3 77
# R4 84
# Name: C, dtype: int32
print(df.ix[mask, ['C', 'D']])
# C D
# R0 61 16
# R3 77 75
# R4 84 86
Meer in panda's documentatie .
Kolommen filteren ("interessant" selecteren, onnodig laten vallen, RegEx gebruiken, enz.)
monster DF genereren
In [39]: df = pd.DataFrame(np.random.randint(0, 10, size=(5, 6)), columns=['a10','a20','a25','b','c','d'])
In [40]: df
Out[40]:
a10 a20 a25 b c d
0 2 3 7 5 4 7
1 3 1 5 7 2 6
2 7 4 9 0 8 7
3 5 8 8 9 6 8
4 8 1 0 4 4 9
toon kolommen met letter 'a'
In [41]: df.filter(like='a')
Out[41]:
a10 a20 a25
0 2 3 7
1 3 1 5
2 7 4 9
3 5 8 8
4 8 1 0
kolommen weergeven met RegEx-filter (b|c|d)
- b
of c
of d
:
In [42]: df.filter(regex='(b|c|d)')
Out[42]:
b c d
0 5 4 7
1 7 2 6
2 0 8 7
3 9 6 8
4 4 4 9
toon alle kolommen behalve die beginnen met a
(met andere woorden alle kolommen verwijderen / neerzetten die voldoen aan gegeven RegEx)
In [43]: df.ix[:, ~df.columns.str.contains('^a')]
Out[43]:
b c d
0 5 4 7
1 7 2 6
2 0 8 7
3 9 6 8
4 4 4 9
Filteren / rijen selecteren met de methode `.query ()`
import pandas as pd
genereer willekeurige DF
df = pd.DataFrame(np.random.randint(0,10,size=(10, 3)), columns=list('ABC'))
In [16]: print(df)
A B C
0 4 1 4
1 0 2 0
2 7 8 8
3 2 1 9
4 7 3 8
5 4 0 7
6 1 5 5
7 6 7 8
8 6 7 3
9 6 4 5
selecteer rijen waarbij waarden in kolom A > 2
en waarden in kolom B < 5
In [18]: df.query('A > 2 and B < 5')
Out[18]:
A B C
0 4 1 4
4 7 3 8
5 4 0 7
9 6 4 5
met de methode .query()
met variabelen voor filtering
In [23]: B_filter = [1,7]
In [24]: df.query('B == @B_filter')
Out[24]:
A B C
0 4 1 4
3 2 1 9
7 6 7 8
8 6 7 3
In [25]: df.query('@B_filter in B')
Out[25]:
A B C
0 4 1 4
Padafhankelijke segmentering
Het kan nodig zijn om de elementen van een reeks of de rijen van een dataframe te doorlopen op een manier dat het volgende element of de volgende rij afhankelijk is van het eerder geselecteerde element of rij. Dit wordt padafhankelijkheid genoemd.
Denk aan de volgende tijdreeks s
met onregelmatige frequentie.
#starting python community conventions
import numpy as np
import pandas as pd
# n is number of observations
n = 5000
day = pd.to_datetime(['2013-02-06'])
# irregular seconds spanning 28800 seconds (8 hours)
seconds = np.random.rand(n) * 28800 * pd.Timedelta(1, 's')
# start at 8 am
start = pd.offsets.Hour(8)
# irregular timeseries
tidx = day + start + seconds
tidx = tidx.sort_values()
s = pd.Series(np.random.randn(n), tidx, name='A').cumsum()
s.plot();
Laten we een padafhankelijke voorwaarde aannemen. Beginnend met het eerste lid van de serie, wil ik elk volgend element zodanig grijpen dat het absolute verschil tussen dat element en het huidige element groter is dan of gelijk is aan x
.
We zullen dit probleem oplossen met behulp van python-generatoren.
Generator functie
def mover(s, move_size=10):
"""Given a reference, find next value with
an absolute difference >= move_size"""
ref = None
for i, v in s.iteritems():
if ref is None or (abs(ref - v) >= move_size):
yield i, v
ref = v
Dan kunnen we een nieuwe moves
als volgt definiëren
moves = pd.Series({i:v for i, v in mover(s, move_size=10)},
name='_{}_'.format(s.name))
Ze beide uitgezet
moves.plot(legend=True)
s.plot(legend=True)
Het analogon voor dataframes zou zijn:
def mover_df(df, col, move_size=2):
ref = None
for i, row in df.iterrows():
if ref is None or (abs(ref - row.loc[col]) >= move_size):
yield row
ref = row.loc[col]
df = s.to_frame()
moves_df = pd.concat(mover_df(df, 'A', 10), axis=1).T
moves_df.A.plot(label='_A_', legend=True)
df.A.plot(legend=True)
Verkrijg de eerste / laatste n rijen van een dataframe
Om de eerste of laatste paar records van een dataframe te bekijken, kunt u de methoden head
en tail
Gebruik DataFrame.head([n])
om de eerste n rijen te retourneren
df.head(n)
Gebruik DataFrame.tail([n])
om de laatste n rijen terug te geven.
df.tail(n)
Zonder het argument n, retourneren deze functies 5 rijen.
Merk op dat de plaknotatie voor head
/ tail
zou zijn:
df[:10] # same as df.head(10)
df[-10:] # same as df.tail(10)
Selecteer afzonderlijke rijen in het dataframe
Laat
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6]})
df
# Output:
# col_1 col_2
# 0 A 3
# 1 B 4
# 2 A 3
# 3 B 5
# 4 C 6
Om de verschillende waarden in col_1
, kunt u Series.unique()
df['col_1'].unique()
# Output:
# array(['A', 'B', 'C'], dtype=object)
Maar Series.unique () werkt alleen voor een enkele kolom.
Om de geselecteerde unieke col_1, col_2 van SQL te simuleren , kunt u DataFrame.drop_duplicates()
:
df.drop_duplicates()
# col_1 col_2
# 0 A 3
# 1 B 4
# 3 B 5
# 4 C 6
Hiermee krijgt u alle unieke rijen in het dataframe. Dus indien
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6], 'col_3':[0,0.1,0.2,0.3,0.4]})
df
# Output:
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 2 A 3 0.2
# 3 B 5 0.3
# 4 C 6 0.4
df.drop_duplicates()
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 2 A 3 0.2
# 3 B 5 0.3
# 4 C 6 0.4
Als u wilt opgeven welke kolommen moeten worden gebruikt bij het selecteren van unieke records, geeft u deze door als argumenten
df = pd.DataFrame({'col_1':['A','B','A','B','C'], 'col_2':[3,4,3,5,6], 'col_3':[0,0.1,0.2,0.3,0.4]})
df.drop_duplicates(['col_1','col_2'])
# Output:
# col_1 col_2 col_3
# 0 A 3 0.0
# 1 B 4 0.1
# 3 B 5 0.3
# 4 C 6 0.4
# skip last column
# df.drop_duplicates(['col_1','col_2'])[['col_1','col_2']]
# col_1 col_2
# 0 A 3
# 1 B 4
# 3 B 5
# 4 C 6
Bron: Hoe "onderscheidend" te selecteren over meerdere dataframekolommen in panda's? .
Filter rijen met ontbrekende gegevens (NaN, Geen, NaT)
Als u een dataframe hebt met ontbrekende gegevens ( NaN
, pd.NaT
, None
), kunt u onvolledige rijen filteren
df = pd.DataFrame([[0,1,2,3],
[None,5,None,pd.NaT],
[8,None,10,None],
[11,12,13,pd.NaT]],columns=list('ABCD'))
df
# Output:
# A B C D
# 0 0 1 2 3
# 1 NaN 5 NaN NaT
# 2 8 NaN 10 None
# 3 11 12 13 NaT
DataFrame.dropna
alle rijen met ten minste één veld met ontbrekende gegevens
df.dropna()
# Output:
# A B C D
# 0 0 1 2 3
Gebruik de subset
om alleen de rijen te laten vallen waar gegevens ontbreken bij opgegeven kolommen
df.dropna(subset=['C'])
# Output:
# A B C D
# 0 0 1 2 3
# 2 8 NaN 10 None
# 3 11 12 13 NaT
Gebruik de optie inplace = True
voor in-place vervanging door het gefilterde frame.