pandas
Indexation et sélection de données
Recherche…
Sélectionnez colonne par étiquette
# 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
Détails supplémentaires sur: http://pandas.pydata.org/pandas-docs/version/0.18.0/indexing.html#selection-by-label
Sélectionner par position
La iloc
méthode (abréviation de l' emplacement entier) permet de sélectionner les lignes d'une trame de données en fonction de leur indice de position. De cette façon, on peut découper des cadres de données comme on le fait avec le découpage des listes de Python.
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
L'emplacement des lignes peut être combiné avec l'emplacement des colonnes
df.iloc[:, 1] # the 1st column
# Out[15]:
# a 22
# b 44
# c 66
# Name: 1, dtype: int64
Voir aussi: Sélection par position
Trancher avec des étiquettes
Lorsque vous utilisez des étiquettes, le début et la fin sont inclus dans les résultats.
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
Lignes R0
à 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
Notez que loc
diffère d' iloc
car iloc
exclut l'index de fin
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
Colonnes C
à 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
Sélection mixte et sélection basée sur une étiquette
Trame de données:
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
Sélectionnez les lignes par position et les colonnes par libellé:
df.ix[1:3, 'C':'E']
Out[19]:
C D E
R1 5 58 0
R2 36 51 27
Si l'index est entier, .ix
utilisera des libellés plutôt que des positions:
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: []
Indexation booléenne
On peut sélectionner des lignes et des colonnes d'un dataframe en utilisant des tableaux booléens.
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
Plus dans la documentation des pandas .
Filtrage des colonnes (en sélectionnant "intéressant", en supprimant des données inutiles, en utilisant RegEx, etc.)
générer un échantillon DF
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
affiche les colonnes contenant la lettre '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
affiche les colonnes à l'aide du filtre RegEx (b|c|d)
- b
ou c
ou 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
afficher toutes les colonnes sauf celles commençant par a
(en d'autres termes, supprimer / supprimer toutes les colonnes satisfaisant à RegEx donné)
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
Filtrage / sélection de lignes en utilisant la méthode `.query ()`
import pandas as pd
générer des DF aléatoires
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
sélectionnez les lignes où les valeurs de la colonne A > 2
et les valeurs de la colonne 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
utiliser la méthode .query()
avec des variables pour le filtrage
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
Tranchage dépendant du chemin
Il peut être nécessaire de parcourir les éléments d’une série ou les lignes d’un dataframe de manière à ce que l’élément suivant ou la ligne suivante dépende de l’élément ou de la ligne précédemment sélectionnés. Ceci s'appelle la dépendance de chemin.
Considérons la série chronologique suivant s
avec une fréquence irrégulière.
#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();
Supposons une condition dépendant du chemin. En commençant par le premier membre de la série, je veux saisir chaque élément suivant de sorte que la différence absolue entre cet élément et l'élément actuel soit supérieure ou égale à x
.
Nous allons résoudre ce problème en utilisant des générateurs de python.
Fonction générateur
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
Ensuite, nous pouvons définir une nouvelle série de moves
comme ça
moves = pd.Series({i:v for i, v in mover(s, move_size=10)},
name='_{}_'.format(s.name))
Les tracer tous les deux
moves.plot(legend=True)
s.plot(legend=True)
L'analogique pour les dataframes serait:
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)
Récupère les premières / dernières n lignes d'un dataframe
Pour voir le premier ou le dernier enregistrement d’un dataframe, vous pouvez utiliser les méthodes head
et tail
Pour renvoyer les n premières lignes, utilisez DataFrame.head([n])
df.head(n)
Pour retourner les n dernières lignes, utilisez DataFrame.tail([n])
df.tail(n)
Sans l'argument n, ces fonctions renvoient 5 lignes.
Notez que la notation de tranche pour head
/ tail
serait:
df[:10] # same as df.head(10)
df[-10:] # same as df.tail(10)
Sélectionnez des lignes distinctes sur l'ensemble des données
Laisser
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
Pour obtenir les valeurs distinctes dans col_1
vous pouvez utiliser Series.unique()
df['col_1'].unique()
# Output:
# array(['A', 'B', 'C'], dtype=object)
Mais Series.unique () ne fonctionne que pour une seule colonne.
Pour simuler la sélection unique col_1, col_2 de SQL, vous pouvez utiliser DataFrame.drop_duplicates()
:
df.drop_duplicates()
# col_1 col_2
# 0 A 3
# 1 B 4
# 3 B 5
# 4 C 6
Cela vous donnera toutes les lignes uniques dans le dataframe. Donc si
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
Pour spécifier les colonnes à prendre en compte lors de la sélection d'enregistrements uniques, transmettez-les comme arguments
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
Source: Comment «sélectionner distinct» sur plusieurs colonnes de trames de données dans les pandas? .
Filtrer les lignes avec les données manquantes (NaN, None, NaT)
Si vous avez un dataframe avec des données manquantes ( NaN
, pd.NaT
, None
), vous pouvez filtrer les lignes incomplètes
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
supprime toutes les lignes contenant au moins un champ avec des données manquantes
df.dropna()
# Output:
# A B C D
# 0 0 1 2 3
Pour simplement supprimer les lignes pour lesquelles il manque des données à des colonnes spécifiées, utilisez le subset
df.dropna(subset=['C'])
# Output:
# A B C D
# 0 0 1 2 3
# 2 8 NaN 10 None
# 3 11 12 13 NaT
Utilisez l'option inplace = True
pour le remplacement sur place avec le cadre filtré.