Como alterar a ordem das colunas do DataFrame?


880

Eu tenho o seguinte DataFrame( df):

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))

Eu adiciono mais colunas por atribuição:

df['mean'] = df.mean(1)

Como posso mover a coluna meanpara a frente, ou seja, defini-la como primeira coluna, deixando a ordem das outras colunas intocada?



1
Para uma solução generalizada baseada em NumPy, consulte Como mover uma coluna em um dataframe do pandas , assume apenas um nível de coluna, ou seja, não MultiIndex.
Jpp

Depois de pesquisar o suficiente, consegui o melhor link para colunas que reorganizam várias lógicas em termos bastante simples [as colunas reorganizam a lógica dos pandas] [ datasciencemadesimple.com/…
ravibeli

Respostas:


853

Uma maneira fácil seria reatribuir o quadro de dados com uma lista das colunas, reorganizadas conforme necessário.

Isto é o que você tem agora:

In [6]: df
Out[6]:
          0         1         2         3         4      mean
0  0.445598  0.173835  0.343415  0.682252  0.582616  0.445543
1  0.881592  0.696942  0.702232  0.696724  0.373551  0.670208
2  0.662527  0.955193  0.131016  0.609548  0.804694  0.632596
3  0.260919  0.783467  0.593433  0.033426  0.512019  0.436653
4  0.131842  0.799367  0.182828  0.683330  0.019485  0.363371
5  0.498784  0.873495  0.383811  0.699289  0.480447  0.587165
6  0.388771  0.395757  0.745237  0.628406  0.784473  0.588529
7  0.147986  0.459451  0.310961  0.706435  0.100914  0.345149
8  0.394947  0.863494  0.585030  0.565944  0.356561  0.553195
9  0.689260  0.865243  0.136481  0.386582  0.730399  0.561593

In [7]: cols = df.columns.tolist()

In [8]: cols
Out[8]: [0L, 1L, 2L, 3L, 4L, 'mean']

Reorganize colsda maneira que desejar. Foi assim que mudei o último elemento para a primeira posição:

In [12]: cols = cols[-1:] + cols[:-1]

In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]

Em seguida, reordene o quadro de dados da seguinte maneira:

In [16]: df = df[cols]  #    OR    df = df.ix[:, cols]

In [17]: df
Out[17]:
       mean         0         1         2         3         4
0  0.445543  0.445598  0.173835  0.343415  0.682252  0.582616
1  0.670208  0.881592  0.696942  0.702232  0.696724  0.373551
2  0.632596  0.662527  0.955193  0.131016  0.609548  0.804694
3  0.436653  0.260919  0.783467  0.593433  0.033426  0.512019
4  0.363371  0.131842  0.799367  0.182828  0.683330  0.019485
5  0.587165  0.498784  0.873495  0.383811  0.699289  0.480447
6  0.588529  0.388771  0.395757  0.745237  0.628406  0.784473
7  0.345149  0.147986  0.459451  0.310961  0.706435  0.100914
8  0.553195  0.394947  0.863494  0.585030  0.565944  0.356561
9  0.561593  0.689260  0.865243  0.136481  0.386582  0.730399

17
caso você obtenha "não é possível concatenar 'str' e 'listar objetos", verifique se [] o valor str em cols: cols = [cols [7]] + cols [: 7] + cols [8:]
moeabdol

3
@FooBar Isso não é uma união definida, é uma concatenação de duas listas ordenadas.
Aman

3
@ Aman Estou apenas apontando que seu código está obsoleto. O manuseio da sua postagem fica a seu critério.
FooBar

2
@FooBar, o tipo de colsé list; permite até duplicatas (que serão descartadas quando usadas no quadro de dados). Você está pensando em Indexobjetos.
28917 alexis

8
Isso implica copiar TODOS os dados, o que é altamente ineficiente. Eu gostaria que os pandas tivessem uma maneira de fazer isso sem criar uma cópia.
Konstantin

442

Você também pode fazer algo assim:

df = df[['mean', '0', '1', '2', '3']]

Você pode obter a lista de colunas com:

cols = list(df.columns.values)

A saída produzirá:

['0', '1', '2', '3', 'mean']

... que é fácil de reorganizar manualmente antes de colocá-lo na primeira função


8
Você também pode obter a lista de colunas com lista (df.columns)
Jim

8
oudf.columns.tolist()
Jim

Para iniciantes como eu, reorganize a lista que você recebe de cols. Então df = df [cols], ou seja, a lista reorganizada é descartada na primeira expressão sem apenas um conjunto de colchetes.
21418 Sid

Os nomes das colunas serão inteiros em 3.x df = df[['mean1', 0, 1, 2, 3]]
prosti

1
Não acho que seja uma boa resposta, pois não fornece código para alterar a ordem das colunas de qualquer dataframe. Digamos que eu importe um arquivo csv como pandas pd como pd.read_csv(). Como sua resposta pode ser usada para alterar a ordem das colunas?
22419 Robvh

312

Basta atribuir os nomes das colunas na ordem em que você deseja:

In [39]: df
Out[39]: 
          0         1         2         3         4  mean
0  0.172742  0.915661  0.043387  0.712833  0.190717     1
1  0.128186  0.424771  0.590779  0.771080  0.617472     1
2  0.125709  0.085894  0.989798  0.829491  0.155563     1
3  0.742578  0.104061  0.299708  0.616751  0.951802     1
4  0.721118  0.528156  0.421360  0.105886  0.322311     1
5  0.900878  0.082047  0.224656  0.195162  0.736652     1
6  0.897832  0.558108  0.318016  0.586563  0.507564     1
7  0.027178  0.375183  0.930248  0.921786  0.337060     1
8  0.763028  0.182905  0.931756  0.110675  0.423398     1
9  0.848996  0.310562  0.140873  0.304561  0.417808     1

In [40]: df = df[['mean', 4,3,2,1]]

Agora, a coluna 'mean' aparece na frente:

In [41]: df
Out[41]: 
   mean         4         3         2         1
0     1  0.190717  0.712833  0.043387  0.915661
1     1  0.617472  0.771080  0.590779  0.424771
2     1  0.155563  0.829491  0.989798  0.085894
3     1  0.951802  0.616751  0.299708  0.104061
4     1  0.322311  0.105886  0.421360  0.528156
5     1  0.736652  0.195162  0.224656  0.082047
6     1  0.507564  0.586563  0.318016  0.558108
7     1  0.337060  0.921786  0.930248  0.375183
8     1  0.423398  0.110675  0.931756  0.182905
9     1  0.417808  0.304561  0.140873  0.310562

7
Faz uma cópia?
precisa saber é o seguinte

21
@ NicolasMorley - Esta não é a melhor resposta se você tiver, digamos, 1000 colunas no seu df.
AGS

1
ele não parecer que você está atribuindo a <df>.columnscomo você reclamar inicialmente
número Bjorks um fã

8
Esta é a melhor resposta para um pequeno número de colunas.
Dongkyu Choi

2
Esta é apenas uma cópia da resposta anterior de @freddygv. Essa deve ser a resposta aceita, não esta.
James Hirschorn

134

35
Esse recurso futuro pode ser adicionado a pandas? algo parecido df.move(0,df.mean)?
jason

Oh homem, ele ainda funciona assim df_metadata.insert(0,'Db_name',"raw_data")(Código não é relevante para esta discussão)
Aetos

3
Bonita. E isso acontece também.
precisa saber é

2
Esta é uma solução escalável, pois outras soluções estão digitando manualmente os nomes das colunas.
CKM

Isso funciona para a pergunta do OP, ao criar uma nova coluna, mas não para mover uma coluna; tentativa de mover resultados em*** ValueError: cannot insert mean, already exists
spinup

122

No seu caso,

df = df.reindex(columns=['mean',0,1,2,3,4])

fará exatamente o que você quiser.

No meu caso (forma geral):

df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))

2
Tentei definir, copy=Falsemas parece que reindex_axisainda cria uma cópia.
Konstantin

1
@ Konstantin, você pode criar outra pergunta sobre esse problema? Seria melhor ter mais contexto
Alvaro Joao

57

Você precisa criar uma nova lista de suas colunas na ordem desejada e, em seguida, usar df = df[cols]para reorganizar as colunas nessa nova ordem.

cols = ['mean']  + [col for col in df if col != 'mean']
df = df[cols]

Você também pode usar uma abordagem mais geral. Neste exemplo, a última coluna (indicada por -1) é inserida como a primeira coluna.

cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]

Você também pode usar essa abordagem para reordenar as colunas na ordem desejada, se elas estiverem presentes no DataFrame.

inserted_cols = ['a', 'b', 'c']
cols = ([col for col in inserted_cols if col in df] 
        + [col for col in df if col not in inserted_cols])
df = df[cols]

47
import numpy as np
import pandas as pd
df = pd.DataFrame()
column_names = ['x','y','z','mean']
for col in column_names: 
    df[col] = np.random.randint(0,100, size=10000)

Você pode experimentar as seguintes soluções:

Solução 1:

df = df[ ['mean'] + [ col for col in df.columns if col != 'mean' ] ]

Solução 2:


df = df[['mean', 'x', 'y', 'z']]

Solução 3:

col = df.pop("mean")
df = df.insert(0, col.name, col)

Solução 4:

df.set_index(df.columns[-1], inplace=True)
df.reset_index(inplace=True)

Solução 5:

cols = list(df)
cols = [cols[-1]] + cols[:-1]
df = df[cols]

solução 6:

order = [1,2,3,0] # setting column's order
df = df[[df.columns[i] for i in order]]

Comparação de tempo:

Solução 1:

Tempos de CPU: usuário 1,05 ms, sys: 35 µs, total: 1,08 ms Tempo de parede: 995 µs

Solução 2 :

Tempos de CPU: usuário 933 µs, sys: 0 ns, total: 933 µs Tempo de parede: 800 µs

Solução 3 :

Tempos de CPU: usuário 0 ns, sys: 1,35 ms, total: 1,35 ms Tempo de parede: 1,08 ms

Solução 4 :

Tempos de CPU: usuário 1,23 ms, sys: 45 µs, total: 1,27 ms Tempo de parede: 986 µs

Solução 5 :

Tempos de CPU: usuário 1,09 ms, sys: 19 µs, total: 1,11 ms Tempo de parede: 949 µs

Solução 6 :

Tempos de CPU: usuário 955 µs, sys: 34 µs, total: 989 µs Tempo de parede: 859 µs


1
Uma resposta tão bonita, obrigado.
qasimalbaqali 19/03

1
solução 1 é o que eu precisava, pois tenho muitas colunas (53), obrigado
ratnesh

@Pygirl, que valor mostra o tempo de consumo real? (usuário, sys, tempo total ou de parede)
sergzemsk 10/04

1
Esta é para mim a melhor resposta para o problema. Tantas soluções (incluindo uma que eu precisava) e abordagem simples. Obrigado!
Gustavo Rottgering

1
Solução 6 (sem compreensão da lista):df = df.iloc[:, [1, 2, 3, 0]]
Dmitriy Work

43

A partir de agosto de 2018:

Se os nomes das colunas forem muito longos para digitar, você poderá especificar o novo pedido por meio de uma lista de números inteiros com as posições:

Dados:

          0         1         2         3         4      mean
0  0.397312  0.361846  0.719802  0.575223  0.449205  0.500678
1  0.287256  0.522337  0.992154  0.584221  0.042739  0.485741
2  0.884812  0.464172  0.149296  0.167698  0.793634  0.491923
3  0.656891  0.500179  0.046006  0.862769  0.651065  0.543382
4  0.673702  0.223489  0.438760  0.468954  0.308509  0.422683
5  0.764020  0.093050  0.100932  0.572475  0.416471  0.389390
6  0.259181  0.248186  0.626101  0.556980  0.559413  0.449972
7  0.400591  0.075461  0.096072  0.308755  0.157078  0.207592
8  0.639745  0.368987  0.340573  0.997547  0.011892  0.471749
9  0.050582  0.714160  0.168839  0.899230  0.359690  0.438500

Exemplo genérico:

new_order = [3,2,1,4,5,0]
print(df[df.columns[new_order]])  

          3         2         1         4      mean         0
0  0.575223  0.719802  0.361846  0.449205  0.500678  0.397312
1  0.584221  0.992154  0.522337  0.042739  0.485741  0.287256
2  0.167698  0.149296  0.464172  0.793634  0.491923  0.884812
3  0.862769  0.046006  0.500179  0.651065  0.543382  0.656891
4  0.468954  0.438760  0.223489  0.308509  0.422683  0.673702
5  0.572475  0.100932  0.093050  0.416471  0.389390  0.764020
6  0.556980  0.626101  0.248186  0.559413  0.449972  0.259181
7  0.308755  0.096072  0.075461  0.157078  0.207592  0.400591
8  0.997547  0.340573  0.368987  0.011892  0.471749  0.639745
9  0.899230  0.168839  0.714160  0.359690  0.438500  0.050582

E para o caso específico da pergunta do OP:

new_order = [-1,0,1,2,3,4]
df = df[df.columns[new_order]]
print(df)

       mean         0         1         2         3         4
0  0.500678  0.397312  0.361846  0.719802  0.575223  0.449205
1  0.485741  0.287256  0.522337  0.992154  0.584221  0.042739
2  0.491923  0.884812  0.464172  0.149296  0.167698  0.793634
3  0.543382  0.656891  0.500179  0.046006  0.862769  0.651065
4  0.422683  0.673702  0.223489  0.438760  0.468954  0.308509
5  0.389390  0.764020  0.093050  0.100932  0.572475  0.416471
6  0.449972  0.259181  0.248186  0.626101  0.556980  0.559413
7  0.207592  0.400591  0.075461  0.096072  0.308755  0.157078
8  0.471749  0.639745  0.368987  0.340573  0.997547  0.011892
9  0.438500  0.050582  0.714160  0.168839  0.899230  0.359690

O principal problema dessa abordagem é que chamar o mesmo código várias vezes criará resultados diferentes a cada vez, portanto, é preciso ter cuidado :)


17

Essa função evita que você precise listar todas as variáveis ​​do seu conjunto de dados apenas para solicitar algumas delas.

def order(frame,var):
    if type(var) is str:
        var = [var] #let the command take a string or list
    varlist =[w for w in frame.columns if w not in var]
    frame = frame[var+varlist]
    return frame 

São necessários dois argumentos, o primeiro é o conjunto de dados, o segundo são as colunas no conjunto de dados que você deseja trazer para a frente.

Portanto, no meu caso, tenho um conjunto de dados chamado Frame com as variáveis ​​A1, A2, B1, B2, Total e Data. Se eu quero trazer o Total para a frente, tudo o que preciso fazer é:

frame = order(frame,['Total'])

Se eu quero trazer Total e Data para a frente, então eu faço:

frame = order(frame,['Total','Date'])

EDITAR:

Outra maneira útil de usar isso é que, se você tiver uma tabela desconhecida e estiver procurando variáveis ​​com um termo específico, como VAR1, VAR2, ... poderá executar algo como:

frame = order(frame,[v for v in frame.columns if "VAR" in v])

17

Eu mesmo tive uma pergunta semelhante e só queria acrescentar o que decidi. Eu gostei do reindex_axis() methodpara alterar a ordem das colunas. Isso funcionou:

df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)

Um método alternativo baseado no comentário de @Jorge:

df = df.reindex(columns=['mean'] + list(df.columns[:-1]))

Embora reindex_axispareça ser um pouco mais rápido em micro benchmarks que reindex, acho que prefiro o último por sua franqueza.


6
Esta foi uma boa solução, mas reindex_axis será preterido. Eu usei o reindex e funcionou muito bem.
Jorge

15

Simplesmente faça,

df = df[['mean'] + df.columns[:-1].tolist()]

TypeError: Não é possível converter o objeto 'int' para str implicitamente
parvij

poderia ser API mudou, você também pode fazer isso ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order
Napitupulu Jon

1
Uma variação disso funcionou bem para mim. Com uma lista existente headers, que foi usada para criar um ditado que foi usado para criar o DataFrame, liguei df.reindex(columns=headers). O único problema que encontrei foi que eu já havia telefonado df.set_index('some header name', inplace=True); portanto, quando a reindexação foi concluída, ela adicionou outra coluna denominada, some header namejá que a coluna original agora era o índice. Quanto a sintaxe acima especificado, ['mean'] + df.columnsno interpretador python me dáIndex(u'meanAddress', u'meanCity', u'meanFirst Name'...
hlongmore

1
@hlongmore: Eu não sei qual é o seu código anterior, mas a edição deve funcionar (usando 0.19.2) #
Napitupulu Jon

A edição realmente funciona (estou no 0.20.2). No meu caso, eu já tenho as colunas que quero, então acho que df.reindex () é o que realmente devo usar.
hlongmore

11

Você pode fazer o seguinte (tomando emprestado partes da resposta de Aman):

cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))

cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]

df = df[cols]

10

Basta digitar o nome da coluna que deseja alterar e definir o índice para o novo local.

def change_column_order(df, col_name, index):
    cols = df.columns.tolist()
    cols.remove(col_name)
    cols.insert(index, col_name)
    return df[cols]

Para o seu caso, seria assim:

df = change_column_order(df, 'mean', 0)

Isso é subestimado
zelusp 27/01

8

Movendo qualquer coluna para qualquer posição:

import pandas as pd
df = pd.DataFrame({"A": [1,2,3], 
                   "B": [2,4,8], 
                   "C": [5,5,5]})

cols = df.columns.tolist()
column_to_move = "C"
new_position = 1

cols.insert(new_position, cols.pop(cols.index(column_to_move)))
df = df[cols]

7

Eu acho que essa é uma solução um pouco mais limpa:

df.insert(0,'mean', df.pop("mean"))

Essa solução é um pouco semelhante à solução do @JoeHeffer, mas esse é um liner.

Aqui, removemos a coluna "mean"do quadro de dados e a anexamos ao índice 0com o mesmo nome da coluna.


5

Aqui está uma maneira de mover uma coluna existente que modificará o quadro de dados existente.

my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)

5

Esta pergunta foi respondida antes, mas reindex_axis está obsoleta agora, então eu sugiro usar:

df.reindex(sorted(df.columns), axis=1)

19
Não, isso é diferente. Lá, o usuário deseja classificar todas as colunas por nome. Aqui eles desejam mover uma coluna para a primeira coluna, mantendo a ordem das outras colunas intocadas.
SMCI

1
E se você não os quiser classificados?
Chankey Pathak

isso retorna uma cópia, não funciona no local
spinup

3

Que tal usar "T"?

df.T.reindex(['mean',0,1,2,3,4]).T

3

@clocker: Sua solução foi muito útil para mim, pois eu queria trazer duas colunas na frente de um dataframe onde não sei exatamente os nomes de todas as colunas, porque elas são geradas a partir de uma declaração dinâmica antes. Portanto, se você estiver na mesma situação: Para trazer as colunas à frente que você conhece o nome e depois deixá-las seguir "todas as outras colunas", eu vim com a seguinte solução geral;

df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)

3

set():

Uma abordagem simples é usada set(), especialmente quando você tem uma lista longa de colunas e não deseja manipulá-las manualmente:

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]

2
Um cuidado: a ordem das colunas vai embora se você colocá-lo em conjunto
pvarma

Interessante! @ user1930402 Tentei a abordagem acima em várias ocasiões e nunca tive nenhum problema. Vou checar novamente.
Shoresh

2

Gostei da resposta de Shoresh para usar a funcionalidade de conjunto para remover colunas quando você não conhece o local, no entanto, isso não funcionou para o meu objetivo, pois preciso manter a ordem da coluna original (que possui rótulos arbitrários).

Eu tenho isso para trabalho embora usando IndexedSet do pacote Bolton.

Também precisei adicionar novamente vários rótulos de coluna; portanto, para um caso mais geral, usei o seguinte código:

from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set(['mean', 'std']))
cols[0:0] =['mean', 'std']
df = df[cols]

Espero que isso seja útil para quem procura neste tópico uma solução geral.


Estou um pouco surpreso! Uso setcom esse objetivo com bastante frequência e nunca tive que lidar com pedidos.
Shoresh

2

Você pode usar o reindexque pode ser usado para ambos os eixos:

df
#           0         1         2         3         4      mean
# 0  0.943825  0.202490  0.071908  0.452985  0.678397  0.469921
# 1  0.745569  0.103029  0.268984  0.663710  0.037813  0.363821
# 2  0.693016  0.621525  0.031589  0.956703  0.118434  0.484254
# 3  0.284922  0.527293  0.791596  0.243768  0.629102  0.495336
# 4  0.354870  0.113014  0.326395  0.656415  0.172445  0.324628
# 5  0.815584  0.532382  0.195437  0.829670  0.019001  0.478415
# 6  0.944587  0.068690  0.811771  0.006846  0.698785  0.506136
# 7  0.595077  0.437571  0.023520  0.772187  0.862554  0.538182
# 8  0.700771  0.413958  0.097996  0.355228  0.656919  0.444974
# 9  0.263138  0.906283  0.121386  0.624336  0.859904  0.555009

df.reindex(['mean', *range(5)], axis=1)

#        mean         0         1         2         3         4
# 0  0.469921  0.943825  0.202490  0.071908  0.452985  0.678397
# 1  0.363821  0.745569  0.103029  0.268984  0.663710  0.037813
# 2  0.484254  0.693016  0.621525  0.031589  0.956703  0.118434
# 3  0.495336  0.284922  0.527293  0.791596  0.243768  0.629102
# 4  0.324628  0.354870  0.113014  0.326395  0.656415  0.172445
# 5  0.478415  0.815584  0.532382  0.195437  0.829670  0.019001
# 6  0.506136  0.944587  0.068690  0.811771  0.006846  0.698785
# 7  0.538182  0.595077  0.437571  0.023520  0.772187  0.862554
# 8  0.444974  0.700771  0.413958  0.097996  0.355228  0.656919
# 9  0.555009  0.263138  0.906283  0.121386  0.624336  0.859904

2

Aqui está uma função para fazer isso para qualquer número de colunas.

def mean_first(df):
    ncols = df.shape[1]        # Get the number of columns
    index = list(range(ncols)) # Create an index to reorder the columns
    index.insert(0,ncols)      # This puts the last column at the front
    return(df.assign(mean=df.mean(1)).iloc[:,index]) # new df with last column (mean) first

2

Método mais hacky do livro

df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})

2

Eu acho que essa função é mais direta. Você só precisa especificar um subconjunto de colunas no início ou no final ou em ambos:

def reorder_df_columns(df, start=None, end=None):
    """
        This function reorder columns of a DataFrame.
        It takes columns given in the list `start` and move them to the left.
        Its also takes columns in `end` and move them to the right.
    """
    if start is None:
        start = []
    if end is None:
        end = []
    assert isinstance(start, list) and isinstance(end, list)
    cols = list(df.columns)
    for c in start:
        if c not in cols:
            start.remove(c)
    for c in end:
        if c not in cols or c in start:
            end.remove(c)
    for c in start + end:
        cols.remove(c)
    cols = start + cols + end
    return df[cols]

1

Creio que a resposta de @ Aman é a melhor se você souber a localização da outra coluna.

Se você não souber a localização de mean, mas tiver apenas seu nome, não poderá recorrer diretamente a cols = cols[-1:] + cols[:-1]. A seguir, é a próxima melhor coisa que eu poderia fazer:

meanDf = pd.DataFrame(df.pop('mean'))
# now df doesn't contain "mean" anymore. Order of join will move it to left or right:
meanDf.join(df) # has mean as first column
df.join(meanDf) # has mean as last column

1

Basta virar ajuda frequentemente.

df[df.columns[::-1]]

Ou apenas embaralhe para dar uma olhada.

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]

0

A maioria das respostas não generalizou o suficiente e o método pandas reindex_axis é um pouco tedioso, portanto, ofereço uma função simples para mover um número arbitrário de colunas para qualquer posição usando um dicionário no qual key = nome da coluna e value = position para a qual mover. Se o seu quadro de dados for grande, passe True para 'big_data' e a função retornará a lista de colunas ordenadas. E você pode usar essa lista para dividir seus dados.

def order_column(df, columns, big_data = False):

    """Re-Orders dataFrame column(s)
       Parameters : 
       df      -- dataframe
       columns -- a dictionary:
                  key   = current column position/index or column name
                  value = position to move it to  
       big_data -- boolean 
                  True = returns only the ordered columns as a list
                          the user user can then slice the data using this
                          ordered column
                  False = default - return a copy of the dataframe
    """
    ordered_col = df.columns.tolist()

    for key, value in columns.items():

        ordered_col.remove(key)
        ordered_col.insert(value, key)

    if big_data:

        return ordered_col

    return df[ordered_col]

# e.g.
df = pd.DataFrame({'chicken wings': np.random.rand(10, 1).flatten(), 'taco': np.random.rand(10,1).flatten(),
                          'coffee': np.random.rand(10, 1).flatten()})
df['mean'] = df.mean(1)

df = order_column(df, {'mean': 0, 'coffee':1 })

>>>

resultado

col = order_column(df, {'mean': 0, 'coffee':1 }, True)

col
>>>
['mean', 'coffee', 'chicken wings', 'taco']

# you could grab it by doing this

df = df[col]

0

Eu tenho um caso de uso muito específico para reordenar nomes de colunas em pandas. Às vezes, estou criando uma nova coluna em um quadro de dados que se baseia em uma coluna existente. Por padrão, os pandas inserem minha nova coluna no final, mas quero que a nova coluna seja inserida ao lado da coluna existente da qual ela derivou.

insira a descrição da imagem aqui

def rearrange_list(input_list, input_item_to_move, input_item_insert_here):
    '''
    Helper function to re-arrange the order of items in a list.
    Useful for moving column in pandas dataframe.

    Inputs:
        input_list - list
        input_item_to_move - item in list to move
        input_item_insert_here - item in list, insert before 

    returns:
        output_list
    '''
    # make copy for output, make sure it's a list
    output_list = list(input_list)

    # index of item to move
    idx_move = output_list.index(input_item_to_move)

    # pop off the item to move
    itm_move = output_list.pop(idx_move)

    # index of item to insert here
    idx_insert = output_list.index(input_item_insert_here)

    # insert item to move into here
    output_list.insert(idx_insert, itm_move)

    return output_list


import pandas as pd

# step 1: create sample dataframe
df = pd.DataFrame({
    'motorcycle': ['motorcycle1', 'motorcycle2', 'motorcycle3'],
    'initial_odometer': [101, 500, 322],
    'final_odometer': [201, 515, 463],
    'other_col_1': ['blah', 'blah', 'blah'],
    'other_col_2': ['blah', 'blah', 'blah']
})
print('Step 1: create sample dataframe')
display(df)
print()

# step 2: add new column that is difference between final and initial
df['change_odometer'] = df['final_odometer']-df['initial_odometer']
print('Step 2: add new column')
display(df)
print()

# step 3: rearrange columns
ls_cols = df.columns
ls_cols = rearrange_list(ls_cols, 'change_odometer', 'final_odometer')
df=df[ls_cols]
print('Step 3: rearrange columns')
display(df)

0

Uma solução bastante direta que funcionou para mim é usar .reindex no df.columns:

df=df[df.columns.reindex(['mean',0,1,2,3,4])[0]]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.