Selección de varias columnas en un marco de datos pandas


Tengo datos en diferentes columnas pero no se como extraerlos para guardarlos en otra variable.

index  a   b   c
1      2   3   4
2      3   4   5

Cómo selecciono 'a', 'b' ¿y guardarlo en df1?

Lo intenté

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']

Ninguno parece funcionar.

(Edición menor)

Author: RegressForward, 2012-07-02

11 answers

Los nombres de las columnas (que son cadenas) no se pueden cortar de la manera en que lo intentaste.

Aquí tienes un par de opciones. Si sabe por contexto qué variables desea dividir, puede devolver una vista de solo esas columnas pasando una lista a la sintaxis __getitem__ (las []'s).

df1 = df[['a','b']]

Alternativamente, si importa indexarlos numéricamente y no por su nombre (digamos que su código debería hacer esto automáticamente sin conocer los nombres de las dos primeras columnas), entonces usted puede hacer esto en su lugar:

df1 = df.iloc[:,0:2] # Remember that Python does not slice inclusive of the ending index.

Además, debe familiarizarse con la idea de una vista de un objeto Pandas frente a una copia de ese objeto. El primero de los métodos anteriores devolverá una nueva copia en memoria del subobjeto deseado (las secciones deseadas).

A veces, sin embargo, hay convenciones de indexación en Pandas que no hacen esto y en su lugar le dan una nueva variable que solo se refiere al mismo trozo de memoria que el subobjeto o segmento en el objeto original. Este sucederá con la segunda forma de indexación, por lo que puede modificarla con la función copy() para obtener una copia regular. Cuando esto sucede, cambiar lo que crees que es el objeto cortado a veces puede alterar el objeto original. Siempre es bueno estar pendiente de esto.

df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df
 907
Author: ely,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-17 23:25:11

Asumiendo que sus nombres de columna (df.columns) son ['index','a','b','c'], entonces los datos que desea están en el 3rd & 4th columns. Si no conoce sus nombres cuando se ejecuta su script, puede hacer esto

newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.

Como EMS señala en su respuesta, df.ix divide las columnas de forma un poco más concisa, pero la interfaz de corte .columns podría ser más natural porque utiliza la sintaxis de indexación/corte de la lista python 1-D de vainilla.

WARN: 'index' es un mal nombre para una columna DataFrame. Esa misma etiqueta también se utiliza para el atributo real df.index, una matriz Index. Así que su columna es devuelta por df['index'] y el índice de DataFrame real es devuelto por df.index. Un Index es un tipo especial de Series optimizado para buscar los valores de sus elementos. Para df.index es para buscar filas por su etiqueta. Ese atributo df.columns es también un array pd.Index, para buscar columnas por sus etiquetas.

 71
Author: hobs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:48

A partir de la versión 0.11.0, las columnas pueden cortarse de la manera en que intentó usar el .loc indexador:

df.loc[:, 'C':'E']

Devuelve las columnas C hasta E.


Una demostración en un DataFrame generado aleatoriamente:

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 6)), 
                  columns=list('ABCDEF'), 
                  index=['R{}'.format(i) for i in range(100)])
df.head()

Out: 
     A   B   C   D   E   F
R0  99  78  61  16  73   8
R1  62  27  30  80   7  76
R2  15  53  80  27  44  77
R3  75  65  47  30  84  86
R4  18   9  41  62   1  82

Para obtener las columnas de C a E (tenga en cuenta que a diferencia del corte de enteros, 'E' se incluye en las columnas):

df.loc[:, 'C':'E']

Out: 
      C   D   E
R0   61  16  73
R1   30  80   7
R2   80  27  44
R3   47  30  84
R4   41  62   1
R5    5  58   0
...

Lo mismo funciona para seleccionar filas basadas en etiquetas. Obtener las filas 'R6' a 'R10' de los columnas:

df.loc['R6':'R10', 'C':'E']

Out: 
      C   D   E
R6   51  27  31
R7   83  19  18
R8   11  67  65
R9   78  27  29
R10   7  16  94

.loc también acepta una matriz booleana para que pueda seleccionar las columnas cuya entrada correspondiente en la matriz es True. Por ejemplo, df.columns.isin(list('BCD')) devuelve array([False, True, True, True, False, False], dtype=bool) - True si el nombre de la columna está en la lista ['B', 'C', 'D']; False, de lo contrario.

df.loc[:, df.columns.isin(list('BCD'))]

Out: 
      B   C   D
R0   78  61  16
R1   27  30  80
R2   53  80  27
R3   65  47  30
R4    9  41  62
R5   78   5  58
...
 60
Author: ayhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-29 16:14:38
In [39]: df
Out[39]: 
   index  a  b  c
0      1  2  3  4
1      2  3  4  5

In [40]: df1 = df[['b', 'c']]

In [41]: df1
Out[41]: 
   b  c
0  3  4
1  4  5
 50
Author: Wes McKinney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-08 17:55:12

Me doy cuenta de que esta pregunta es bastante antigua, pero en la última versión de pandas hay una manera fácil de hacer exactamente esto. Los nombres de columna (que son cadenas) pueden cortarse de la manera que desee.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
 34
Author: zerovector,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-04 14:05:35

Puede proporcionar una lista de columnas que se eliminarán y devolver el DataFrame con solo las columnas necesarias utilizando la función drop() en un DataFrame de Pandas.

Solo digo

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)

Devolvería un DataFrame con solo las columnas b y c.

El método drop se documenta aquí.

 15
Author: Muthu Chithambara Jothi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-03 22:16:59

Encontré este método muy útil:

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]

Se pueden encontrar más detalles aquí

 13
Author: Alvis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-02 18:38:13

Solo use: seleccionará la columna b y c.

df1=pd.DataFrame()
df1=df[['b','c']]

Entonces u puede llamar a df1:

df1
 7
Author: Akash Nayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-10 09:35:50

Si desea obtener un elemento por índice de fila y nombre de columna, puede hacerlo igual que df['b'][0]. Es tan simple como se puede imaginar.

O puede usar df.ix[0,'b'], uso mixto de índice y etiqueta.

Nota: Desde v0. 20 ix ha sido obsoleto a favor de loc / iloc.

 3
Author: W.Perrin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 14:38:55

Los diferentes enfoques discutidos en las respuestas anteriores se basan en la suposición de que o bien el usuario conoce los índices de columna para soltar o subconjunto en, o el usuario desea subconjunto de un dataframe utilizando un rango de columnas (por ejemplo, entre 'C' : 'E'). pandas.DataFrame.drop () es ciertamente una opción para subconjuntos de datos basados en una lista de columnas definidas por el usuario (aunque debe tener cuidado de que siempre use copia de dataframe y inplace los parámetros no deben configurarse a Verdadero !!)

Otra opción es usar pandas.columna.difference () , que establece una diferencia en los nombres de las columnas, y devuelve un tipo de índice de matriz que contiene las columnas deseadas. La siguiente es la solución:

df = pd.DataFrame([[2,3,4],[3,4,5]],columns=['a','b','c'],index=[1,2])
columns_for_differencing = ['a']
df1 = df.copy()[df.columns.difference(columns_for_differencing)]
print(df1)

La salida sería: b c 1 3 4 2 4 5

 2
Author: Harshit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-21 21:28:41

Comenzando en 0.21.0, usando .loc o [] con una lista con una o más etiquetas faltantes, está en desuso, a favor de .reindex. Entonces, la respuesta a su pregunta es:

df1 = df.reindex(columns=['b','c'])

En versiones anteriores, usar .loc[list-of-labels] funcionaría siempre y cuando se encontrara al menos 1 de las claves (de lo contrario generaría un KeyError). Este comportamiento está obsoleto y ahora muestra un mensaje de advertencia. La alternativa recomendada es utilizar .reindex().

Leer más en https://pandas.pydata.org/pandas-docs/stable/indexing.html#reindexing

 0
Author: tozCSS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-15 18:13:41