Extraer columnas seleccionadas específicas a un nuevo DataFrame como copia

185

Tengo un DataFrame de pandas con 4 columnas y quiero crear un nuevo DataFrame que solo tenga tres de las columnas. Esta pregunta es similar a: Extraer columnas específicas de un marco de datos, pero para pandas no R. El siguiente código no funciona, genera un error y ciertamente no es la forma pandanic de hacerlo.

import pandas as pd
old = pd.DataFrame({'A' : [4,5], 'B' : [10,20], 'C' : [100,50], 'D' : [-30,-50]})
new = pd.DataFrame(zip(old.A, old.C, old.D)) # raises TypeError: data argument can't be an iterator 

¿Cuál es la forma pandasnic de hacerlo?

SpeedCoder5
fuente

Respuestas:

359

Hay una manera de hacer esto y en realidad se parece a R

new = old[['A', 'C', 'D']].copy()

Aquí solo está seleccionando las columnas que desea del marco de datos original y creando una variable para ellas. Si desea modificar el nuevo marco de datos, probablemente quiera usarlo .copy()para evitar a SettingWithCopyWarning.

Se filterusará un método alternativo que creará una copia por defecto:

new = old.filter(['A','B','D'], axis=1)

Finalmente, dependiendo del número de columnas en su marco de datos original, podría ser más sucinto expresar esto usando un drop(esto también creará una copia por defecto):

new = old.drop('B', axis=1)
johnchase
fuente
20
Una advertencia si solo está copiando una columna: en old[['A']].copy(), se requieren los corchetes dobles para crear un nuevo marco de datos. Tenga en cuenta que old['A'].copy()solo creará una serie.
intotecho 01 de
19

La forma más fácil es

new = old[['A','C','D']]

.

stidmatt
fuente
3
Esto no está haciendo una copia a menos que llame explícitamente a .copy ()
Sylvain el
esto copia por defecto.
Nguai al
1
@Nguaial no se especifica el comportamiento de la indexación simple. No sabrá si obtiene una copia o una vista. Consulte la documentación para obtener más detalles: pandas.pydata.org/pandas-docs/stable/user_guide/…
Ole Fass
8

Otra forma más simple parece ser:

new = pd.DataFrame([old.A, old.B, old.C]).transpose()

donde old.column_namete daré una serie. Haga una lista de todas las series de columnas que desea conservar y páselo al constructor DataFrame. Necesitamos hacer una transposición para ajustar la forma.

In [14]:pd.DataFrame([old.A, old.B, old.C]).transpose()
Out[14]: 
   A   B    C
0  4  10  100
1  5  20   50
Golpear
fuente
funciona, pero no si column_name tiene caracteres especiales.
Jim
oh no había pensado en eso
Hit
3

Forma funcional genérica

def select_columns(data_frame, column_names):
    new_frame = data_frame.loc[:, column_names]
    return new_frame

Específico para su problema anterior

selected_columns = ['A', 'C', 'D']
new = select_columns(old, selected_columns)
Deslin Naidoo
fuente
2

Si desea tener un nuevo marco de datos, entonces:

import pandas as pd
old = pd.DataFrame({'A' : [4,5], 'B' : [10,20], 'C' : [100,50], 'D' : [-30,-50]})
new=  old[['A', 'C', 'D']]
Una mentira
fuente
1

Por lo que puedo decir, no necesariamente necesita especificar el eje cuando utiliza la función de filtro.

new = old.filter(['A','B','D'])

devuelve el mismo marco de datos que

new = old.filter(['A','B','D'], axis=1)
Ellen
fuente
1

columnas por índice:

# selected column index: 1, 6, 7
new = old.iloc[: , [1, 6, 7]].copy() 
sailfish009
fuente