python - seleccionar - Seleccionando mĂșltiples columnas en un marco de datos de pandas
seleccionar filas y columnas en python (12)
Tengo datos en diferentes columnas, pero no sé cómo extraerlos para guardarlos en otra variable.
index a b c
1 2 3 4
2 3 4 5
¿Cómo selecciono ''a''
, ''b''
y lo guardo en df1?
Lo intenté
df1 = df[''a'':''b'']
df1 = df.ix[:, ''a'':''b'']
Ninguno parece funcionar.
(Edición menor)
A partir de la versión 0.11.0, las columnas se pueden dividir de la manera en que intentó usar el indexador .loc
:
df.loc[:, ''C'':''E'']
devuelve las columnas C
a la 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 de la división de enteros, se incluye ''E'' 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. Obtenga las filas ''R6'' a ''R10'' de esas 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'']
; Falso, 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
...
Asumiendo que los nombres de sus columnas ( df.columns
) son [''index'',''a'',''b'',''c'']
, entonces los datos que desea están en las columnas 3 y 4. Si no conoce sus nombres cuando se ejecuta el script, puede hacer esto
newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.
Como señala EMS en su respuesta , df.ix
columnas de forma un poco más concisa, pero la interfaz de .columns
puede ser más natural porque utiliza la sintaxis de indexación / segmentación de la lista de pitón 1-D de vainilla.
WARN: ''index''
es un mal nombre para una columna DataFrame
. Esa misma etiqueta también se usa para el atributo df.index
real, una matriz de Index
. Por lo tanto, df[''index'']
devuelve su columna y df.index devuelve el índice DataFrame real. Un Index
es un tipo especial de Series
optimizado para la búsqueda de los valores de sus elementos. Para df.index es para buscar filas por su etiqueta. Ese atributo df.columns
también es una matriz pd.Index
, para buscar columnas por sus etiquetas.
Comenzando en 0.21.0, el uso de .loc
o []
con una lista con una o más etiquetas faltantes, está en desuso, a favor de .reindex
. Entonces, la respuesta a tu pregunta es:
df1 = df.reindex(columns=[''b'',''c''])
En versiones anteriores, el uso de .loc[list-of-labels]
funcionaría siempre y cuando se encontrara al menos una de las claves (de lo contrario generaría un KeyError
). Este comportamiento está en desuso y ahora muestra un mensaje de advertencia. La alternativa recomendada es usar .reindex()
.
Lea más en https://pandas.pydata.org/pandas-docs/stable/indexing.html#reindexing
Encontré este método muy útil:
# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]
Más detalles se pueden encontrar here
Estoy bastante seguro de que este no es un enfoque optimizado, pero se puede considerar como uno diferente.
usando iterows
`df1= pd.DataFrame() #creating an empty dataframe
for index,i in df.iterrows():
df1.loc[index,''A'']=df.loc[index,''A'']
df1.loc[index,''B'']=df.loc[index,''B'']
df1.head()
Los diferentes enfoques analizados en las respuestas anteriores se basan en la suposición de que el usuario sabe que los índices de columna deben eliminarse o se pueden subcontratar, o que el usuario desea crear un subconjunto de un marco de datos utilizando un rango de columnas (por ejemplo, entre ''C'': ''E'') . pandas.DataFrame.drop () es ciertamente una opción para subcontratar datos en base a una lista de columnas definidas por el usuario (¡¡¡aunque hay que tener cuidado de no usar siempre la copia del marco de datos y los parámetros in situ no deben configurarse como Verdaderos !!)
Otra opción es usar pandas.columns.difference () , que establece una diferencia de conjunto en los nombres de columna 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: bc 1 3 4 2 4 5
Los nombres de columna (que son cadenas) no se pueden dividir de la manera que lo intentó.
Aquí tienes un par de opciones. Si sabe por el contexto qué variables desea dividir, solo puede devolver una vista de solo esas columnas pasando una lista a la sintaxis __getitem__
(las []).
df1 = df[[''a'',''b'']]
Alternativamente, si es importante indexarlos numéricamente y no por su nombre (digamos que su código debería hacer esto automáticamente sin saber los nombres de las dos primeras columnas), entonces puede hacerlo 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 en un objeto Pandas frente a una copia de ese objeto. El primero de los métodos anteriores devolverá una nueva copia en la memoria del subobjeto deseado (los cortes deseados).
A veces, sin embargo, hay convenciones de indexación en Pandas que no lo hacen y en cambio le dan una nueva variable que solo se refiere a la misma porción de memoria que el subobjeto o segmento en el objeto original. Esto ocurrirá con la segunda forma de indexación, por lo que puede modificarlo con la función copy()
para obtener una copia normal. Cuando esto sucede, cambiar lo que crees que es el objeto cortado a veces puede alterar el objeto original. Siempre es bueno estar atento a esto.
df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df
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) se pueden dividir de la forma que desee.
columns = [''b'', ''c'']
df1 = pd.DataFrame(df, columns=columns)
Puede proporcionar una lista de columnas para ser eliminadas y devolver el DataFrame solo con las columnas necesarias usando la función drop()
en un Data Frame 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 de drop
se documenta here .
Si desea obtener un elemento por fila, nombre de columna y columna, puede hacerlo como df[''b''][0]
. Es lo más simple que puedas imaginar.
O puede usar df.ix[0,''b'']
, uso mixto de índice y etiqueta.
Nota: Desde v0.20 ix
ha sido desaprobado en favor de loc
/ iloc
.
solo use: seleccionará las columnas byc.
df1=pd.DataFrame()
df1=df[[''b'',''c'']]
entonces u puede simplemente llamar df1:
df1
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