pandas valeurs uniques plusieurs colonnes
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
'Col3': np.random.random(5)})
Quelle est la meilleure façon de retourner les valeurs uniques de 'Col1' et 'Col2'?
La sortie souhaitée est
'Bob', 'Joe', 'Bill', 'Mary', 'Steve'
6 réponses
pd.unique
renvoie les valeurs uniques d'un tableau d'entrée, ou D'une colonne ou d'un index DataFrame.
L'entrée de cette fonction doit être unidimensionnelle, de sorte que plusieurs colonnes devront être combinées. Le plus simple est de sélectionner les colonnes que vous voulez, puis d'afficher les valeurs dans un tableau NumPy aplati. Toute l'opération ressemble à ceci:
>>> pd.unique(df[['Col1', 'Col2']].values.ravel('K'))
array(['Bob', 'Joe', 'Bill', 'Mary', 'Steve'], dtype=object)
Notez que ravel()
est une méthode de tableau qui renvoie une vue (si possible) d'un tableau multidimensionnel. L'argument 'K'
indique la méthode pour aplatir le tableau dans l'ordre où les éléments sont stockés en mémoire (les pandas stockent généralement les tableaux sous-jacents dans Fortran-contigu order; colonnes avant les lignes). Cela peut être significatif que d'utiliser l'ordre 'C' par défaut de la méthode.
, Une alternative consiste à sélectionner les colonnes et les passer à np.unique
:
>>> np.unique(df[['Col1', 'Col2']].values)
array(['Bill', 'Bob', 'Joe', 'Mary', 'Steve'], dtype=object)
Il n'est pas nécessaire d'utiliser ravel()
ici car la méthode gère les tableaux multidimensionnels. Même ainsi, cela est susceptible d'être plus lent que pd.unique
car il utilise un algorithme basé sur le tri plutôt qu'une table de hachage pour identifier des valeurs uniques.
La différence de vitesse est significative pour les DataFrames plus grandes (surtout s'il n'y a qu'une poignée de valeurs uniques):
>>> df1 = pd.concat([df]*100000, ignore_index=True) # DataFrame with 500000 rows
>>> %timeit np.unique(df1[['Col1', 'Col2']].values)
1 loop, best of 3: 1.12 s per loop
>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel('K'))
10 loops, best of 3: 38.9 ms per loop
>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel()) # ravel using C order
10 loops, best of 3: 49.9 ms per loop
J'ai configuré un DataFrame
avec quelques chaînes simples dans ses colonnes:
>>> df
a b
0 a g
1 b h
2 d a
3 e e
Vous pouvez concaténer les colonnes qui vous intéressent et appeler unique
function:
>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}
Ou:
set(df.Col1) | set(df.Col2)
Non-pandas
solution: en utilisant set ().
import pandas as pd
import numpy as np
df = pd.DataFrame({'Col1' : ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
'Col2' : ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
'Col3' : np.random.random(5)})
print df
print set(df.Col1.append(df.Col2).values)
Sortie:
Col1 Col2 Col3
0 Bob Joe 0.201079
1 Joe Steve 0.703279
2 Bill Bob 0.722724
3 Mary Bob 0.093912
4 Joe Steve 0.766027
set(['Steve', 'Bob', 'Bill', 'Joe', 'Mary'])
Une solution mise à jour utilisant numpy v1.13+ nécessite de spécifier l'axe dans np.unique Si vous utilisez plusieurs colonnes, sinon le tableau est implicitement aplati.
import numpy as np
np.unique(df[['col1', 'col2']], axis=0)
Ce changement a été introduit en novembre 2016: https://github.com/numpy/numpy/commit/1f764dbff7c496d6636dc0430f083ada9ff4e4be
Pour ceux d'entre nous qui aiment toutes les choses pandas, appliquer, et bien sûr les fonctions lambda:
df['Col3'] = df[['Col1', 'Col2']].apply(lambda x: ''.join(x), axis=1)