pandas valeurs uniques plusieurs colonnes


134
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 renvoyer les valeurs uniques de «Col1» et «Col2»?

La sortie souhaitée est

'Bob', 'Joe', 'Bill', 'Mary', 'Steve'

3
Voir également les combinaisons uniques de valeurs dans les colonnes sélectionnées dans le cadre de données pandas et compter pour une question différente mais connexe. La réponse choisie ici utilisedf1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Paul Rougieux

Réponses:


198

pd.unique renvoie les valeurs uniques d'un tableau d'entrée, 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 moyen le plus simple consiste à sélectionner les colonnes souhaitées, puis à afficher les valeurs dans un tableau NumPy aplati. L'ensemble de l'opération ressemble à ceci:

>>> pd.unique(df[['Col1', 'Col2']].values.ravel('K'))
array(['Bob', 'Joe', 'Bill', 'Mary', 'Steve'], dtype=object)

Notez qu'il ravel()s'agit d'une méthode de tableau qui renvoie une vue (si possible) d'un tableau multidimensionnel. L'argument 'K'indique à la méthode d'aplatir le tableau dans l'ordre dans lequel les éléments sont stockés en mémoire (les pandas stockent généralement les tableaux sous-jacents dans l' ordre contigu à Fortran ; les colonnes avant les lignes). Cela peut être beaucoup plus rapide que d'utiliser l'ordre par défaut «C» de la méthode.


Une autre méthode consiste à sélectionner les colonnes et à les transmettre à 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 dans ce cas, cela sera probablement plus lent que pd.uniquecar 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 volumineux (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

2
Comment récupérer un dataframe au lieu d'un tableau?
Lisle

1
@Lisle: les deux méthodes renvoient un tableau NumPy, vous devrez donc le construire manuellement, par exemple pd.DataFrame(unique_values). Il n'y a pas de bon moyen de récupérer directement un DataFrame.
Alex Riley

@Lisle depuis qu'il a utilisé pd.unique il renvoie un numpy.ndarray en sortie finale. Est-ce ce que vous demandiez?
Ash Upadhyay

1
@Lisle, peut-être celui-ci df = df.drop_duplicates (subset = ['C1', 'C2', 'C3'])?
patate tickly le

14

J'ai configuré un DataFrameavec 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 la uniquefonction:

>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)

7
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}

Ou:

set(df.Col1) | set(df.Col2)


1

Non- pandassolution: 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)

Production:

   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'])

1

pour ceux d'entre nous qui aiment toutes les choses pandas, appliquent et bien sûr les fonctions lambda:

df['Col3'] = df[['Col1', 'Col2']].apply(lambda x: ''.join(x), axis=1)

1

voici une autre façon


import numpy as np
set(np.concatenate(df.values))

0
list(set(df[['Col1', 'Col2']].as_matrix().reshape((1,-1)).tolist()[0]))

La sortie sera ['Mary', 'Joe', 'Steve', 'Bob', 'Bill']

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.