Encontrar el recuento de elementos distintos en DataFrame en cada columna

Estoy tratando de encontrar el conteo de valores distintos en cada columna usando Pandas. Esto es lo que hice.

import pandas as pd import numpy as np # Generate data. NROW = 10000 NCOL = 100 df = pd.DataFrame(np.random.randint(1, 100000, (NROW, NCOL)), columns=['col' + x for x in np.arange(NCOL).astype(str)]) 

Necesito contar el número de elementos distintos para cada columna, como esto:

 col0 9538 col1 9505 col2 9524 

¿Cuál sería la forma más eficiente de hacer esto, ya que este método se aplicará a archivos que tengan un tamaño superior a 1.5GB?


Basado en las respuestas, df.apply(lambda x: len(x.unique())) es el más rápido ( cuaderno ).

%timeit df.apply(lambda x: len(x.unique())) 10 loops, best of 3: 49.5 ms per loop %timeit df.nunique() 10 loops, best of 3: 59.7 ms per loop %timeit df.apply(pd.Series.nunique) 10 loops, best of 3: 60.3 ms per loop %timeit df.T.apply(lambda x: x.nunique(), axis=1) 10 loops, best of 3: 60.5 ms per loop

A partir de los pandas 0.20 podemos usar nunique directamente en DataFrame s, es decir:

 df.nunique() a 4 b 5 c 1 dtype: int64 

Otras opciones heredadas:

Usted podría hacer una transposición de la df y luego usar apply call nunique row-wise:

 In [205]: df = pd.DataFrame({'a':[0,1,1,2,3],'b':[1,2,3,4,5],'c':[1,1,1,1,1]}) df Out[205]: abc 0 0 1 1 1 1 2 1 2 1 3 1 3 2 4 1 4 3 5 1 In [206]: df.T.apply(lambda x: x.nunique(), axis=1) Out[206]: a 4 b 5 c 1 dtype: int64 

EDITAR

Como señalado por @ajcr, la transposición es innecesaria:

 In [208]: df.apply(pd.Series.nunique) Out[208]: a 4 b 5 c 1 dtype: int64 

Ya hay algunas respuestas geniales aquí 🙂 pero esta parece faltar:

 df.apply(lambda x: x.nunique()) 

A partir de los pandas 0.20.0, DataFrame.nunique() también está disponible.

Pandas.Series tiene una función .value_counts() que proporciona exactamente lo que desea. Echa un vistazo a la documentación de la función .

Recientemente, tengo los mismos problemas de contar el valor único de cada columna en DataFrame, y encontré alguna otra función que se ejecuta más rápido que la función de apply :

 #Select the way how you want to store the output, could be pd.DataFrame or Dict, I will use Dict to demonstrate: col_uni_val={} for i in df.columns: col_uni_val[i] = len(df[i].unique()) #Import pprint to display dic nicely: import pprint pprint.pprint(col_uni_val) 

Esto me funciona casi dos veces más rápido que df.apply(lambda x: len(x.unique()))

 df.apply(lambda x: len(x.unique()))