Come modificare l'ordine delle colonne DataFrame?


880

Ho il seguente DataFrame( df):

import numpy as np
import pandas as pd

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

Aggiungo più colonne per compito:

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

Come posso spostare la colonna meanin primo piano, ovvero impostarla come prima colonna lasciando intatto l'ordine delle altre colonne?



1
Per una soluzione generalizzata basata su NumPy, vedere Come spostare una colonna in un frame di dati panda , presuppone solo un livello di colonna, ovvero no MultiIndex.
jpp

Dopo aver cercato abbastanza, ho ottenuto questo miglior collegamento per le colonne che riordinano più logiche in termini piuttosto semplici [le colonne riorganizzano la logica per i panda] [ datasciencemadesimple.com/…
ravibeli

Risposte:


853

Un modo semplice sarebbe quello di riassegnare il frame di dati con un elenco di colonne, riorganizzato secondo necessità.

Questo è quello che hai ora:

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']

Riorganizza colscome preferisci. Ecco come ho spostato l'ultimo elemento nella prima posizione:

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

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

Quindi riordinare il frame di dati in questo modo:

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
nel caso in cui ottieni "impossibile concatenare gli oggetti 'str' e 'list'" assicurati di [] il valore str in cols: cols = [cols [7]] + cols [: 7] + cols [8:]
moeabdol

3
@FooBar Non è un sindacato impostato, è una concatenazione di due elenchi ordinati.
Aman,

3
@Aman sto solo sottolineando che il tuo codice è obsoleto. La gestione del tuo post è a tua discrezione.
FooBar,

2
@FooBar, il tipo di colsè list; consente anche duplicati (che verranno scartati quando utilizzati sul frame di dati). Stai pensando agli Indexoggetti.
alexis,

8
Ciò implica la copia di TUTTI i dati, il che è altamente inefficiente. Avrei voluto che i panda avessero modo di farlo senza crearne una copia.
Konstantin,

442

Potresti anche fare qualcosa del genere:

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

Puoi ottenere l'elenco delle colonne con:

cols = list(df.columns.values)

L'output produrrà:

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

... che è quindi facile riorganizzare manualmente prima di farlo cadere nella prima funzione


8
È inoltre possibile ottenere l'elenco di colonne con elenco (df.columns)
Jim,

8
oppuredf.columns.tolist()
Jim,

Per i neofiti come me, riorganizza l'elenco che ricevi dai cols. Quindi df = df [cols], ovvero l'elenco riorganizzato viene rilasciato nella prima espressione senza un solo set di parentesi.
Sid,

I nomi delle colonne saranno numeri interi in 3.x df = df[['mean1', 0, 1, 2, 3]]
prosti

1
Non penso che questa sia una buona risposta in quanto non fornisce codice su come modificare l'ordine delle colonne di alcun frame di dati. Suppongo di importare un file CSV come Panda PDA come pd.read_csv(). In che modo è possibile utilizzare la risposta per modificare l'ordine delle colonne?
Robvh,

312

Basta assegnare i nomi delle colonne nell'ordine desiderato:

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]]

Ora, la colonna "media" viene visualizzata in primo piano:

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
Fa una copia?
user3226167

21
@ NicholasMorley - Questa non è la risposta migliore se hai, diciamo, 1000 colonne nel tuo df.
AGS,

1
non sembra che ti stia assegnando a <df>.columnscome asserisci inizialmente
Bjorks numero uno fan

8
Questa è la risposta migliore per un piccolo numero di colonne.
Dongkyu Choi,

2
Questa è solo una copia della risposta precedente di @freddygv. Quella dovrebbe essere la risposta accettata, non questa.
James Hirschorn,

134

35
Potrebbe essere una funzionalità futura aggiungere a pandas? qualcosa di simile adf.move(0,df.mean) ?
Jason,

Oh amico, funziona anche così df_metadata.insert(0,'Db_name',"raw_data") (Codice non rilevante per questa discussione)
Aetos,

3
Bellissimo. E succede anche sul posto.
Cucu8

2
Questa è una soluzione scalabile poiché altre soluzioni digitano manualmente i nomi delle colonne.
CKM

Questo funziona per la domanda del PO, quando si crea una nuova colonna, ma non per spostare una colonna; *** ValueError: cannot insert mean, already exists
prova

122

Nel tuo caso,

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

farà esattamente quello che vuoi.

Nel mio caso (modulo generale):

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

2
Ho provato a impostare copy=Falsema sembra che reindex_axiscrea ancora una copia.
Konstantin,

1
@Konstantin puoi creare un'altra domanda su questo problema? Sarebbe meglio avere più contesto
Alvaro Joao,

57

È necessario creare un nuovo elenco delle colonne nell'ordine desiderato, quindi utilizzare df = df[cols]per riorganizzare le colonne in questo nuovo ordine.

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

Puoi anche usare un approccio più generale. In questo esempio, l'ultima colonna (indicata da -1) viene inserita come prima colonna.

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

È inoltre possibile utilizzare questo approccio per riordinare le colonne nell'ordine desiderato se sono presenti nel 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)

Puoi provare le seguenti soluzioni:

Soluzione 1:

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

Soluzione 2:


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

Soluzione 3:

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

Soluzione 4:

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

Soluzione 5:

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

soluzione 6:

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

Confronto temporale:

Soluzione 1:

Tempi CPU: utente 1,05 ms, sys: 35 µs, totale: 1,08 ms Tempo parete: 995 µs

Soluzione 2 :

Tempi CPU: utente 933 µs, sys: 0 ns, totale: 933 µs Tempo parete: 800 µs

Soluzione 3 :

Tempi CPU: utente 0 ns, sys: 1,35 ms, totale: 1,35 ms Tempo muro: 1,08 ms

Soluzione 4 :

Tempi CPU: utente 1,23 ms, sys: 45 µs, totale: 1,27 ms Tempo parete: 986 µs

Soluzione 5 :

Tempi CPU: utente 1,09 ms, sys: 19 µs, totale: 1,11 ms Tempo parete: 949 µs

Soluzione 6 :

Tempi CPU: utente 955 µs, sys: 34 µs, totale: 989 µs Tempo parete: 859 µs


1
Una risposta così bella, grazie.
qasimalbaqali,

1
la soluzione 1 è ciò di cui avevo bisogno in quanto ho troppe colonne (53), grazie
ratnesh

@Pygirl quale valore mostra il tempo reale richiesto? (utente, sistema, tempo totale o a parete)
sergzemsk,

1
Questa è per me la migliore risposta al problema. Tante soluzioni (inclusa quella di cui avevo bisogno) e un approccio semplice. Grazie!
Gustavo Rottgering,

1
Soluzione 6 (nessuna comprensione dell'elenco):df = df.iloc[:, [1, 2, 3, 0]]
Dmitriy Work

43

Da agosto 2018:

Se i nomi delle colonne sono troppo lunghi da digitare, è possibile specificare il nuovo ordine tramite un elenco di numeri interi con le posizioni:

Dati:

          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

Esempio generico:

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 per il caso specifico della domanda di 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

Il problema principale con questo approccio è che chiamare lo stesso codice più volte creerà risultati diversi ogni volta, quindi bisogna stare attenti :)


17

Questa funzione evita di dover elencare ogni variabile nel set di dati solo per ordinarne alcune.

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 

Sono necessari due argomenti, il primo è il set di dati, il secondo sono le colonne nel set di dati che si desidera portare in primo piano.

Quindi nel mio caso ho un set di dati chiamato Frame con le variabili A1, A2, B1, B2, Total e Date. Se voglio portare Total in primo piano, tutto ciò che devo fare è:

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

Se voglio portare il totale e la data in primo piano, allora faccio:

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

MODIFICARE:

Un altro modo utile per usarlo è, se hai una tabella sconosciuta e stai cercando variabili con un particolare termine in esse, come VAR1, VAR2, ... puoi eseguire qualcosa del tipo:

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

17

Mi sono imbattuto in una domanda simile e volevo solo aggiungere quello su cui mi ero posto. Mi è piaciuto il reindex_axis() methodper cambiare l'ordine delle colonne. Questo ha funzionato:

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

Un metodo alternativo basato sul commento di @Jorge:

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

Anche se reindex_axissembra essere leggermente più veloce nei micro benchmark rispetto a reindex, penso che preferisco quest'ultimo per la sua immediatezza.


6
Questa è stata una buona soluzione, ma reindex_axis sarà deprecato. Ho usato reindex e ha funzionato bene.
Jorge

15

Semplicemente,

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

TypeError: impossibile convertire l'oggetto 'int' in modo implicito
parvij

potrebbe essere l'API è cambiata, puoi anche farlo ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order
Napitupulu Jon

1
Una variazione di questo ha funzionato bene per me. Con un elenco esistente headers, che è stato utilizzato per creare un dict che è stato quindi utilizzato per creare il DataFrame, ho chiamato df.reindex(columns=headers). L'unico problema che ho df.set_index('some header name', inplace=True)riscontrato era che avevo già chiamato , quindi quando il reindex è stato fatto, ha aggiunto un'altra colonna chiamata some header namepoiché la colonna originale era ora l'indice. Per quanto riguarda la sintassi sopra specificata, ['mean'] + df.columnsnell'interprete python mi dàIndex(u'meanAddress', u'meanCity', u'meanFirst Name'...
hlongmore il

1
@hlongmore: Non so che il tuo codice precedente sia, ma la modifica dovrebbe funzionare (usando 0.19.2)
Napitupulu Jon,

La modifica funziona davvero (sono su 0.20.2). Nel mio caso, ho già le colonne che voglio, quindi penso che df.reindex () sia quello che dovrei davvero usare.
hlongmore,

11

Potresti fare quanto segue (prendendo in prestito parti dalla risposta di Aman):

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

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

df = df[cols]

10

Digita semplicemente il nome della colonna che desideri modificare e imposta l'indice per la nuova posizione.

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

Per il tuo caso, questo sarebbe come:

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

Questo è sottovalutato
zelusp

8

Spostare qualsiasi colonna in qualsiasi posizione:

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

Penso che questa sia una soluzione leggermente più ordinata:

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

Questa soluzione è in qualche modo simile alla soluzione di @JoeHeffer ma questa è una linea.

Qui rimuoviamo la colonna "mean"dal frame di dati e la alleghiamo all'indice 0con lo stesso nome di colonna.


5

Ecco un modo per spostare una colonna esistente che modificherà il frame di dati esistente sul posto.

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

5

Questa domanda è stato risposto prima ma reindex_axis è deprecato ora così vorrei suggerire di utilizzo:

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

19
No, è diverso. Lì l'utente vuole ordinare tutte le colonne per nome. Qui vogliono spostare una colonna sulla prima colonna lasciando intatta l'ordine delle altre colonne.
smci,

1
E se non li desideri ordinati?
Chankey Pathak,

questo restituisce una copia, non funziona sul posto
spinup

3

Che ne dici di usare "T"?

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

3

@clocker: La tua soluzione è stata molto utile per me, poiché volevo portare due colonne di fronte a un frame di dati in cui non conosco esattamente i nomi di tutte le colonne, perché sono state generate in precedenza da un'istruzione pivot. Quindi, se ti trovi nella stessa situazione: per mettere in primo piano le colonne di cui conosci il nome e poi lasciarle seguire da "tutte le altre colonne", ho trovato la seguente soluzione generale;

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

3

set():

Viene utilizzato un approccio semplice set(), in particolare quando si dispone di un lungo elenco di colonne e non si desidera gestirle manualmente:

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

2
Un avvertimento: l'ordine delle colonne scompare se lo metti nel set
pvarma,

Interessante! @ user1930402 Ho provato l'approccio sopra in diverse occasioni e non ho mai avuto problemi. Ricontrollerò di nuovo.
Shoresh,

2

Mi è piaciuta la risposta di Shoresh per utilizzare la funzionalità set per rimuovere le colonne quando non si conosce la posizione, tuttavia questo non ha funzionato per il mio scopo in quanto è necessario mantenere l'ordine delle colonne originali (che ha etichette di colonne arbitrarie).

L'ho fatto funzionare usando IndexedSet dal pacchetto boltons.

Avevo anche bisogno di aggiungere nuovamente più etichette di colonna, quindi per un caso più generale ho usato il seguente codice:

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

Spero che questo sia utile a chiunque cerchi questa discussione per una soluzione generale.


Sono un po 'sorpreso! Uso seta questo scopo abbastanza spesso e non ho mai avuto a che fare con l'ordinazione.
Shoresh,

2

È possibile utilizzare reindexquali possono essere utilizzati per entrambi gli assi:

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

Ecco una funzione per farlo per qualsiasi numero di colonne.

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

Il metodo più hackerato nel libro

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

2

Penso che questa funzione sia più semplice. Devi solo specificare un sottoinsieme di colonne all'inizio o alla fine o entrambi:

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

Credo che la risposta di @ Aman sia la migliore se conosci la posizione dell'altra colonna.

Se non conosci la posizione di mean, ma hai solo il suo nome, non puoi ricorrere direttamente a cols = cols[-1:] + cols[:-1]. Di seguito è la cosa migliore che potrei trovare:

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 lanciare aiuta spesso.

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

O semplicemente mescolare per dare un'occhiata.

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

0

La maggior parte delle risposte non è stata abbastanza generalizzata e il metodo panda reindex_axis è un po 'noioso, quindi offro una semplice funzione per spostare un numero arbitrario di colonne in qualsiasi posizione usando un dizionario in cui chiave = nome colonna e valore = posizione in cui spostarsi. Se il tuo dataframe è grande, passa True a 'big_data', quindi la funzione restituirà l'elenco delle colonne ordinate. E potresti usare questo elenco per dividere i tuoi dati.

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 })

>>>

produzione

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

Ho un caso d'uso molto specifico per riordinare i nomi delle colonne nei panda. A volte sto creando una nuova colonna in un dataframe basato su una colonna esistente. Per impostazione predefinita, Panda inserirà la mia nuova colonna alla fine, ma voglio che la nuova colonna venga inserita accanto alla colonna esistente da cui deriva.

inserisci qui la descrizione dell'immagine

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

Una soluzione abbastanza semplice che ha funzionato per me è usare .reindex su df.columns:

df=df[df.columns.reindex(['mean',0,1,2,3,4])[0]]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.