Seleccionar / Excluir conjuntos de columnas en Pandas
Me gustaría crear vistas o dataframes a partir de un dataframe existente basado en selecciones de columnas.
Por ejemplo, me gustaría crear un dataframe df2 a partir de un dataframe df1 que contenga todas las columnas excepto dos de ellas. Intenté hacer lo siguiente, pero no funcionó:
import numpy as np
import pandas as pd
# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
# Try to create a second dataframe df2 from df with all columns except 'B' and D
my_cols = set(df.columns)
my_cols.remove('B').remove('D')
# This returns an error ("unhashable type: set")
df2 = df[my_cols]
¿Qué estoy haciendo mal? Quizás de manera más general, ¿qué mecanismos tiene Panda para soportar la selección y exclusiones de conjuntos arbitrarios de columnas de un dataframe?
9 answers
Puede soltar las columnas que no necesita O Seleccionar las que necesita
# Using DataFrame.drop
df.drop(df.columns[[1, 2]], axis=1, inplace=True)
# drop by Name
df1 = df1.drop(['B', 'C'], axis=1)
# Select the ones you want
df1 = df[['a','d']]
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-06-12 16:16:58
Hay un nuevo método de índice llamado difference
. Devuelve las columnas originales, con las columnas pasadas como argumento eliminadas.
df2 = df[df.columns.difference(['B', 'D'])]
Aquí, la salida se usa para filtrar las columnas B
y D
de df
.
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-08-16 08:34:48
Realmente no necesitas convertir eso en un conjunto:
cols = [col for col in df.columns if col not in ['B', 'D']]
df2 = df[cols]
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
2013-11-18 02:25:39
También echar un vistazo a la incorporada DataFrame.filter
función.
Enfoque minimalista pero codicioso (suficiente para el df dado):
df.filter(regex="[^BD]")
Enfoque conservador / perezoso (solo coincidencias exactas):
df.filter(regex="^(?!(B|D)$).*$")
Conservador y genérico:
exclude_cols = ['B','C']
df.filter(regex="^(?!({0})$).*$".format('|'.join(exclude_cols)))
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-10-14 09:02:31
Solo necesita convertir su set
a un list
import pandas as pd
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
my_cols = set(df.columns)
my_cols.remove('B')
my_cols.remove('D')
my_cols = list(my_cols)
df2 = df[my_cols]
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
2013-02-18 16:32:43
He aquí cómo crear una copia de una DataFrame
excluyendo una lista de columnas:
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
df2 = df.drop(['B', 'D'], axis=1)
Pero ten cuidado! Mencionas puntos de vista en tu pregunta, sugiriendo que si cambiaste df
, querrías que df2
también cambiara. (Como lo haría una vista en una base de datos.)
Este método no logra eso:
>>> df.loc[0, 'A'] = 999 # Change the first value in df
>>> df.head(1)
A B C D
0 999 -0.742688 -1.980673 -0.920133
>>> df2.head(1) # df2 is unchanged. It's not a view, it's a copy!
A C
0 0.251262 -1.980673
Tenga en cuenta también que esto también es cierto para el método de @piggybox. (Aunque ese método es agradable y hábil y Pitónico. ¡No lo estoy haciendo mal!!)
Para más información sobre vistas vs. copias ver esta respuesta y esta parte de los documentos de Pandas a la que se refiere esa respuesta.
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:18:21
Tienes 4 columnas A,B,C, D
Aquí hay una mejor manera de seleccionar las columnas que necesita para el nuevo dataframe: -
df2 = df1[['A','D']]
Si desea usar números de columna en su lugar, use: -
df2 = df1[[0,3]]
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-06-18 13:56:12
Otra opción, sin dejar caer o filtrar en un bucle:
import numpy as np
import pandas as pd
# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
# include the columns you want
df[df.columns[df.columns.isin(['A', 'B'])]]
# exclude columns you don't want
df[df.columns[~df.columns.isin(['C','D'])]]
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-30 20:41:25
En una línea similar, al leer un archivo, uno puede desear excluir columnas por adelantado, en lugar de leer desperdiciadamente datos no deseados en la memoria y luego descartarlos.
A partir de pandas 0.20.0, usecols
ahora acepta callables .1 Esta actualización permite opciones más flexibles para leer columnas:
skipcols = [...]
read_csv(..., usecols=lambda x: x not in skipcols)
El último patrón es esencialmente el inverso del método tradicional usecols
- solo las columnas especificadas son saltar.
Dado
Datos en un archivo
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
filename = "foo.csv"
df.to_csv(filename)
Código
skipcols = ["B", "D"]
df1 = pd.read_csv(filename, usecols=lambda x: x not in skipcols, index_col=0)
df1
Salida
A C
0 0.062350 0.076924
1 -0.016872 1.091446
2 0.213050 1.646109
3 -1.196928 1.153497
4 -0.628839 -0.856529
...
Detalles
Se escribió un DataFrame en un archivo. Luego se volvió a leer como un DataFrame separado, ahora saltando columnas no deseadas (B
y D
).
Tenga en cuenta que para la situación del OP, ya que los datos ya están creados, el mejor enfoque es la respuesta aceptada, que elimina columnas no deseadas de un objeto existente. Obstante, la técnica presentada aquí es más útil cuando se leen directamente datos de archivos en un DataFrame.
En esta cuestión se formuló una solicitud de opción "skipcols", que se abordó en una cuestión posterior .
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-06-04 17:32:26