2014-11-17 14 views
45
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'], 
        'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'], 
        'Col3': np.random.random(5)}) 

Qual è il modo migliore per restituire i valori univoci di "Col1" e "Col2"?valori unici panda colonne multiple

L'uscita desiderata è

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

risposta

77

pd.unique restituisce i valori univoci da una matrice di input, o colonna dataframe o indice.

L'input per questa funzione deve essere unidimensionale, quindi sarà necessario combinare più colonne. Il modo più semplice è selezionare le colonne che vuoi e quindi visualizzare i valori in un array NumPy appiattito. L'intera operazione è simile al seguente:

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

noti che ravel() è un metodo matrice che restituisce una vista (se possibile) di una matrice multidimensionale. L'argomento 'K' indica al metodo di appiattire la matrice nell'ordine in cui gli elementi sono archiviati in memoria (in genere i panda memorizzano gli array sottostanti in Fortran-contiguous order; le colonne prima delle righe). Questo può essere significativamente maggiore rispetto all'ordine predefinito "C" del metodo.


Un modo alternativo è quello di selezionare le colonne e passarle a np.unique:

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

Non v'è alcuna necessità di utilizzare ravel() qui come metodo gestisce array multidimensionali. Anche così, è probabile che sia più lento di pd.unique poiché utilizza un algoritmo basato su ordinamento piuttosto che una tabella hash per identificare valori univoci.

La differenza di velocità è significativa per DataFrames grandi (soprattutto se ci sono solo una manciata di valori unici):

>>> 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 
+0

Il '.sono richiesti valori nella tua risposta precedente; altrimenti restituisce 'array (['Col1', 'Col2'], dtype = '| S4')' – congusbongus

+0

@congusbongus: grazie per averlo indicato - Ho aggiornato la risposta. Sembra che il '.values' sia necessario per alcune versioni di Pandas/NumPy (stavo testando questo con NumPy 1.9.2 e Pandas 15.2 e funzionava senza). –

+1

Come si ottiene un datagramma invece di un array? – Lisle

1

Non- pandas Using 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) 

uscita:

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

Ho installato un DataFrame con pochi semplici stringhe in esso è colonne:

>>> df 
    a b 
0 a g 
1 b h 
2 d a 
3 e e 

è possibile concatenare le colonne a cui sei interessato e chiamare unique funzione :

>>> pandas.concat([df['a'], df['b']]).unique() 
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object) 
3
In [5]: set(df.Col1).union(set(df.Col2)) 
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'} 

Oppure:

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