Extraindo colunas selecionadas específicas para o novo DataFrame como uma cópia

184

Eu tenho um DataFrame de pandas com 4 colunas e quero criar um novo DataFrame que tenha apenas três das colunas. Esta pergunta é semelhante a: Extrair colunas específicas de um quadro de dados, mas para pandas e não R. O código a seguir não funciona, gera um erro e certamente não é a maneira pandasnic de fazê-lo.

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 

Qual é a maneira pandasnic de fazer isso?

SpeedCoder5
fonte

Respostas:

358

Existe uma maneira de fazer isso e ele realmente se parece com R

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

Aqui você está apenas selecionando as colunas que deseja do quadro de dados original e criando uma variável para elas. Se você quiser modificar o novo quadro de dados, provavelmente usará .copy()para evitar a SettingWithCopyWarning.

Um método alternativo é o uso filterque criará uma cópia por padrão:

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

Por fim, dependendo do número de colunas no quadro de dados original, pode ser mais sucinto expressar isso usando a drop(isso também criará uma cópia por padrão):

new = old.drop('B', axis=1)
johnchase
fonte
20
Cuidado ao copiar apenas uma coluna: Em old[['A']].copy(), os colchetes duplos são necessários para criar um novo quadro de dados. Observe que old['A'].copy()apenas criará uma série.
#
19

A maneira mais fácil é

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

.

stidmatt
fonte
3
Isto não é fazer uma cópia a menos que você chamar explicitamente .Copy ()
Sylvain
isso copia por padrão.
Nguai al
1
@ Nguaial o comportamento da indexação simples não está especificado. Você não saberá se obtém uma cópia ou uma visualização. Consulte a documentação para obter mais detalhes: pandas.pydata.org/pandas-docs/stable/user_guide/…
Ole Fass
8

Outra maneira mais simples parece ser:

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

onde old.column_namelhe dará uma série. Faça uma lista de todas as séries de colunas que você deseja manter e passe-a para o construtor DataFrame. Precisamos fazer uma transposição para ajustar a 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
Acertar
fonte
funciona, mas não se column_name tiver caracteres especiais.
jimh
oh não tinha pensado nisso
bateu
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 o seu problema acima

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

Se você deseja ter um novo quadro de dados, então:

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

Até onde eu sei, você não precisa necessariamente especificar o eixo ao usar a função de filtro.

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

retorna o mesmo quadro de dados que

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

colunas por índice:

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