obtener una lista de columnas de marco de datos de pandas según el tipo de datos

184

Si tengo un marco de datos con las siguientes columnas:

1. NAME                                     object
2. On_Time                                      object
3. On_Budget                                    object
4. %actual_hr                                  float64
5. Baseline Start Date                  datetime64[ns]
6. Forecast Start Date                  datetime64[ns] 

Me gustaría poder decir: aquí hay un marco de datos, ¿me dan una lista de las columnas que son de tipo Object o de tipo DateTime?

Tengo una función que convierte números (Float64) a dos decimales, y me gustaría usar esta lista de columnas de marco de datos, de un tipo particular, y ejecutarla a través de esta función para convertirlos a 2dp.

Tal vez:

For c in col_list: if c.dtype = "Something"
list[]
List.append(c)?
yoshiserry
fuente
44
Cuando llegué a esta pregunta, estaba buscando una manera de crear exactamente la lista en la parte superior. df.dtypeshace eso.
Martin Thoma
Los visitantes también pueden estar interesados ​​en esta pregunta diferente pero relacionada sobre cómo encontrar todos los tipos de objetos dentro de cada columna : ¿Cómo podría detectar subtipos en columnas de objetos pandas? .
jpp

Respuestas:

315

Si desea una lista de columnas de cierto tipo, puede usar groupby:

>>> df = pd.DataFrame([[1, 2.3456, 'c', 'd', 78]], columns=list("ABCDE"))
>>> df
   A       B  C  D   E
0  1  2.3456  c  d  78

[1 rows x 5 columns]
>>> df.dtypes
A      int64
B    float64
C     object
D     object
E      int64
dtype: object
>>> g = df.columns.to_series().groupby(df.dtypes).groups
>>> g
{dtype('int64'): ['A', 'E'], dtype('float64'): ['B'], dtype('O'): ['C', 'D']}
>>> {k.name: v for k, v in g.items()}
{'object': ['C', 'D'], 'int64': ['A', 'E'], 'float64': ['B']}
DSM
fuente
55
Esto es útil como un control de calidad de datos, donde se asegura que las columnas sean del tipo que se espera.
NYCeyes
2
esto no funciona si todas las columnas del marco de datos devuelven el objecttipo, independientemente de su contenido real
user5359531
2
@ user5359531 eso no significa que no esté funcionando, en realidad significa que sus columnas de DataFrame no se convirtieron al tipo que cree que deberían ser, lo que puede suceder por varias razones.
Marc
66
Si solo selecciona columnas por tipo de datos, esta respuesta es obsoleta. Usar en su select_dtypeslugar
Ted Petrou
¿Cómo indexa este marco de datos agrupado después?
Allen Wang
110

A partir de pandas v0.14.1, puede utilizar select_dtypes()para seleccionar columnas por dtype

In [2]: df = pd.DataFrame({'NAME': list('abcdef'),
    'On_Time': [True, False] * 3,
    'On_Budget': [False, True] * 3})

In [3]: df.select_dtypes(include=['bool'])
Out[3]:
  On_Budget On_Time
0     False    True
1      True   False
2     False    True
3      True   False
4     False    True
5      True   False

In [4]: mylist = list(df.select_dtypes(include=['bool']).columns)

In [5]: mylist
Out[5]: ['On_Budget', 'On_Time']
qmorgan
fuente
35

El uso dtypele dará el tipo de datos de la columna deseada:

dataframe['column1'].dtype

Si quieres saber los tipos de datos de toda la columna a la vez , puede plural de utilizar dtypecomo dtypes :

dataframe.dtypes
Ashish Sahu
fuente
1
Esta debería ser la respuesta aceptada, imprime los tipos de datos en casi exactamente el formato que OP quiere.
Abhishek Divekar
1
La pregunta era sobre enumerar solo el tipo de datos específico, por ejemplo, utilizando df.select_dtypes(include=['Object','DateTime']).columnscomo se discute a continuación
DfAC
29

Puede usar la máscara booleana en el atributo dtypes:

In [11]: df = pd.DataFrame([[1, 2.3456, 'c']])

In [12]: df.dtypes
Out[12]: 
0      int64
1    float64
2     object
dtype: object

In [13]: msk = df.dtypes == np.float64  # or object, etc.

In [14]: msk
Out[14]: 
0    False
1     True
2    False
dtype: bool

Puede mirar solo esas columnas con el tipo de letra deseado:

In [15]: df.loc[:, msk]
Out[15]: 
        1
0  2.3456

Ahora puede usar round (o lo que sea) y asignarlo de nuevo:

In [16]: np.round(df.loc[:, msk], 2)
Out[16]: 
      1
0  2.35

In [17]: df.loc[:, msk] = np.round(df.loc[:, msk], 2)

In [18]: df
Out[18]: 
   0     1  2
0  1  2.35  c
Andy Hayden
fuente
Me encantaría poder escribir una función que tome el nombre de un marco de datos y luego devuelva un diccionario de listas, con la clave del diccionario como el tipo de datos y el valor como la lista de columnas del marco de datos que son de ese tipo de datos.
yoshiserry
def col_types (x, pd):
itthrill
14
list(df.select_dtypes(['object']).columns)

Esto debería funcionar

Tanmoy
fuente
7

use df.info(verbose=True)where dfis a pandas datafarme, por defectoverbose=False

Koo
fuente
puede haber problemas de memoria si la tabla es grande
Koo
4

La forma más directa de obtener una lista de columnas de cierto dtype, por ejemplo, 'objeto':

df.select_dtypes(include='object').columns

Por ejemplo:

>>df = pd.DataFrame([[1, 2.3456, 'c', 'd', 78]], columns=list("ABCDE"))
>>df.dtypes

A      int64
B    float64
C     object
D     object
E      int64
dtype: object

Para obtener todas las columnas de tipo 'objeto':

>>df.select_dtypes(include='object').columns

Index(['C', 'D'], dtype='object')

Por solo la lista:

>>list(df.select_dtypes(include='object').columns)

['C', 'D']   
MLKing
fuente
3

Si desea una lista de solo las columnas de objetos que podría hacer:

non_numerics = [x for x in df.columns \
                if not (df[x].dtype == np.float64 \
                        or df[x].dtype == np.int64)]

y luego, si desea obtener otra lista de solo los números:

numerics = [x for x in df.columns if x not in non_numerics]

fuente
0

Se me ocurrió esta línea de tres .

Básicamente, esto es lo que hace:

  1. Obtenga los nombres de columna y sus respectivos tipos de datos.
  2. Opcionalmente lo estoy enviando a un csv.

inp = pd.read_csv('filename.csv') # read input. Add read_csv arguments as needed
columns = pd.DataFrame({'column_names': inp.columns, 'datatypes': inp.dtypes})
columns.to_csv(inp+'columns_list.csv', encoding='utf-8') # encoding is optional

Esto me facilitó la vida al intentar generar esquemas sobre la marcha. Espero que esto ayude

geekidharsh
fuente
0

para yoshiserry;

def col_types(x,pd):
    dtypes=x.dtypes
    dtypes_col=dtypes.index
    dtypes_type=dtypes.value
    column_types=dict(zip(dtypes_col,dtypes_type))
    return column_types
emociona
fuente
0

Yo uso infer_objects ()

Docstring: Intenta inferir mejores tipos para las columnas de objetos.

Intenta la conversión suave de columnas con tipos de objetos, sin modificar las columnas no objeto e inconvertible. Las reglas de inferencia son las mismas que durante la construcción normal de Series / DataFrame.

df.infer_objects().dtypes

como si
fuente