Tengo datos en diferentes columnas, pero no sé cómo extraerlos para guardarlos en otra variable.
index abc 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.
Los diferentes enfoques discutidos en las respuestas anteriores se basan en la suposición de que el usuario conoce los índices de columna para colocar o subconjunto, o el usuario desea subconjunto de un marco de datos utilizando un rango de columnas (por ejemplo, entre 'C': 'E' ).
pandas.DataFrame.drop() es sin duda una opción para crear subconjuntos de datos en función de una lista de columnas definidas por el usuario (¡aunque debe tener cuidado de usar siempre una copia del marco de datos y los parámetros in situ no deben establecerse en True !)
Otra opción es usar pandas.columns.difference() , que establece una diferencia en los nombres de las columnas y devuelve un tipo de matriz de índice 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 5A partir de 0.21.0, el uso de .loc o [] con una lista con una o más etiquetas faltantes está en desuso en favor de .reindex . Entonces, la respuesta a tu pregunta es:
df1 = df.reindex(columns=['b','c']) En versiones anteriores, el uso .loc[list-of-labels] funcionaba siempre que 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() .
Obtenga más información en Indexación y selección de datos .
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']es equivalente a
df[['C', 'D', 'E']] # or df.loc[:, ['C', 'D', 'E']] y devuelve las columnas C a 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: ABCDEF 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 82Para 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: CDE 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: CDE 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 sea 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: BCD R0 78 61 16 R1 27 30 80 R2 53 80 27 R3 65 47 30 R4 9 41 62 R5 78 5 58 ...En la última versión de Pandas hay una manera fácil de hacer exactamente esto. Los nombres de las columnas (que son cadenas) se pueden dividir de la manera que desee.
columns = ['b', 'c'] df1 = pd.DataFrame(df, columns=columns)Puede proporcionar una lista de columnas para eliminar y devolver el DataFrame con solo las columnas necesarias usando la función drop() en un Pandas DataFrame.
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í .
Suponiendo que los nombres de sus columnas ( df.columns ) sean ['index','a','b','c'] , entonces los datos que desea están en la tercera y cuarta columnas. Si no sabe sus nombres cuando se ejecuta su secuencia de comandos, puede hacer esto
newdf = df[df.columns[2:4]] # Remember, Python is zero-offset! The "third" entry is at slot two. Como señala EMS en su respuesta , df.ix columnas de manera un poco más concisa, pero la interfaz de división de .columns podría ser más natural, porque utiliza la sintaxis de división/indexación de listas unidimensionales de Python.
Advertencia : 'index' es un mal nombre para una columna DataFrame . Esa misma etiqueta también se usa para el atributo real df.index , una matriz Index . Por lo tanto, df['index'] devuelve su columna y df.index devuelve el índice real de df.index . 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.
Los nombres de las columnas (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, puede devolver una vista de solo esas columnas pasando una lista a la sintaxis __getitem__ (los []).
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 conocer los nombres de las dos primeras columnas), entonces 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 la memoria del subobjeto deseado (los segmentos deseados).
A veces, sin embargo, hay convenciones de indexación en Pandas que no hacen esto y en su lugar le brindan una nueva variable que solo se refiere a la misma porción de memoria que el subobjeto o segmento en el objeto original. Esto sucederá con la segunda forma de indexación, por lo que puede modificarla con el método .copy() para obtener una copia regular. Cuando esto sucede, cambiar lo que cree 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 Para usar iloc , necesita conocer las posiciones de las columnas (o índices). Como las posiciones de las columnas pueden cambiar, en lugar de índices de codificación fija, puede usar iloc junto con la función get_loc del método de columns del objeto de marco de datos para obtener índices de columna.
{df.columns.get_loc(c): c for idx, c in enumerate(df.columns)} Ahora puede usar este diccionario para acceder a columnas a través de nombres y usando iloc .
In [39]: df Out[39]: index abc 0 1 2 3 4 1 2 3 4 5 In [40]: df1 = df[['b', 'c']] In [41]: df1 Out[41]: bc 0 3 4 1 4 5He visto varias respuestas al respecto, pero una no me quedó clara. ¿Cómo seleccionaría esas columnas de interés?
La respuesta a eso es que si los tiene reunidos en una lista, puede simplemente hacer referencia a las columnas usando la lista.
print(extracted_features.shape) print(extracted_features) (63,) ['f000004' 'f000005' 'f000006' 'f000014' 'f000039' 'f000040' 'f000043' 'f000047' 'f000048' 'f000049' 'f000050' 'f000051' 'f000052' 'f000053' 'f000054' 'f000055' 'f000056' 'f000057' 'f000058' 'f000059' 'f000060' 'f000061' 'f000062' 'f000063' 'f000064' 'f000065' 'f000066' 'f000067' 'f000068' 'f000069' 'f000070' 'f000071' 'f000072' 'f000073' 'f000074' 'f000075' 'f000076' 'f000077' 'f000078' 'f000079' 'f000080' 'f000081' 'f000082' 'f000083' 'f000084' 'f000085' 'f000086' 'f000087' 'f000088' 'f000089' 'f000090' 'f000091' 'f000092' 'f000093' 'f000094' 'f000095' 'f000096' 'f000097' 'f000098' 'f000099' 'f000100' 'f000101' 'f000103'] Tengo la siguiente lista/matriz NumPy extracted_features , especificando 63 columnas. El conjunto de datos original tiene 103 columnas, y me gustaría extraer exactamente esas, luego usaría
dataset[extracted_features]Y terminarás con esto
Esto es algo que usaría con bastante frecuencia en el aprendizaje automático (más específicamente, en la selección de funciones). También me gustaría discutir otras formas, pero creo que ya lo han cubierto otros usuarios de Stack Overflower.
Puedes usar pandas.
Creo el DataFrame:
import pandas as pd df = pd.DataFrame([[1, 2,5], [5,4, 5], [7,7, 8], [7,6,9]], index=['Jane', 'Peter','Alex','Ann'], columns=['Test_1', 'Test_2', 'Test_3'])El marco de datos:
Test_1 Test_2 Test_3 Jane 1 2 5 Peter 5 4 5 Alex 7 7 8 Ann 7 6 9Para seleccionar una o más columnas por nombre:
df[['Test_1', 'Test_3']] Test_1 Test_3 Jane 1 5 Peter 5 5 Alex 7 8 Ann 7 9También puedes usar:
df.Test_2 Y obtienes la columna Test_2 :
Jane 2 Peter 4 Alex 7 Ann 6 También puede seleccionar columnas y filas de estas filas usando .loc() . Esto se llama "rebanar" . Observe que tomo de la columna Test_1 a Test_3 :
df.loc[:, 'Test_1':'Test_3']La "Rebanada" es:
Test_1 Test_2 Test_3 Jane 1 2 5 Peter 5 4 5 Alex 7 7 8 Ann 7 6 9 Y si solo quiere a Peter y Ann de las columnas Test_1 y Test_3 :
df.loc[['Peter', 'Ann'], ['Test_1', 'Test_3']]Usted obtiene:
Test_1 Test_3 Peter 5 5 Ann 7 9También puedes usar df.pop() :
>>> df = pd.DataFrame([('falcon', 'bird', 389.0), ... ('parrot', 'bird', 24.0), ... ('lion', 'mammal', 80.5), ... ('monkey', 'mammal', np.nan)], ... columns=('name', 'class', 'max_speed')) >>> df name class max_speed 0 falcon bird 389.0 1 parrot bird 24.0 2 lion mammal 80.5 3 monkey mammal >>> df.pop('class') 0 bird 1 bird 2 mammal 3 mammal Name: class, dtype: object >>> df name max_speed 0 falcon 389.0 1 parrot 24.0 2 lion 80.5 3 monkey NaN Utilice df.pop(c) .
Si desea obtener un elemento por índice de fila y nombre de columna, puede hacerlo como df['b'][0] . Es tan simple como te puedes imaginar.
O puede usar df.ix[0,'b'] - uso mixto de índice y etiqueta.
Nota: desde v0.20, ix ha quedado obsoleto en favor de loc / iloc .
Un enfoque diferente y fácil: iterar filas
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()con pandas,
con nombres de columnas
dataframe[['column1','column2']]para seleccionar por iloc y columnas específicas con número de índice:
dataframe.iloc[:,[1,2]]con los nombres de columna loc se pueden usar como
dataframe.loc[:,['column1','column2']]Intente usar pandas.DataFrame.get (consulte la documentación ):
import pandas as pd import numpy as np dates = pd.date_range('20200102', periods=6) df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD')) df.get(['A', 'C'])Para seleccionar varias columnas, extráigalas y visualícelas a partir de entonces: df se denomina previamente marco de datos, luego cree un nuevo marco de datos df1 y seleccione las columnas A a D que desea extraer y ver.
df1 = pd.DataFrame(data_frame, columns=['Column A', 'Column B', 'Column C', 'Column D']) df1¡Se mostrarán todas las columnas requeridas!
df[['a', 'b']] # Select all rows of 'a' and 'b'column df.loc[0:10, ['a', 'b']] # Index 0 to 10 select column 'a' and 'b' df.loc[0:10, 'a':'b'] # Index 0 to 10 select column 'a' to 'b' df.iloc[0:10, 3:5] # Index 0 to 10 and column 3 to 5 df.iloc[3, 3:5] # Index 3 of column 3 to 5Puede usar el método pandas.DataFrame.filter para filtrar o reordenar columnas como esta:
df1 = df.filter(['a', 'b'])Esto también es muy útil cuando estás encadenando métodos.
def get_slize(dataframe, start_row, end_row, start_col, end_col): assert len(dataframe) > end_row and start_row >= 0 assert len(dataframe.columns) > end_col and start_col >= 0 list_of_indexes = list(dataframe.columns)[start_col:end_col] ans = dataframe.iloc[start_row:end_row][list_of_indexes] return ansSolo usa esta función
Para excluir algunas columnas, puede soltarlas en el índice de columnas. Por ejemplo:
ABCD 0 1 10 100 1000 1 2 20 200 2000Seleccione todos excepto dos:
df[df.columns.drop(['B', 'D'])]Producción:
AC 0 1 100 1 2 200También puede usar el método truncar para seleccionar columnas intermedias:
df.truncate(before='B', after='C', axis=1)Producción:
BC 0 10 100 1 20 200