Jak zmienić kolejność kolumn DataFrame?

875

Mam następujące DataFrame( df):

import numpy as np
import pandas as pd

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

Dodaję więcej kolumn według przypisania:

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

Jak mogę przenieść kolumnę meanna przód, tzn. Ustawić ją jako pierwszą kolumnę, pozostawiając kolejność pozostałych kolumn nietkniętą?

Timmie
źródło
1
Uogólnione rozwiązanie oparte na NumPy, patrz Jak przenieść kolumnę w ramce danych pandy , zakłada tylko jeden poziom kolumny, tj MultiIndex. Nie .
jpp

Odpowiedzi:

852

Jednym prostym sposobem byłoby ponowne przypisanie ramki danych z listą kolumn, w razie potrzeby zmienioną w kolejności.

Oto co masz teraz:

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

Zmień układ colsw dowolny sposób. W ten sposób przesunąłem ostatni element na pierwszą pozycję:

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

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

Następnie zmień kolejność ramki danych w następujący sposób:

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
Mężczyzna
źródło
17
jeśli otrzymujesz „nie można łączyć” str ”i„ list ”obiektów” upewnij się, że [] wartość str w cols: cols = [cols [7]] + cols [: 7] + cols [8:]
moeabdol
3
@FooBar To nie jest zbiór związków, to połączenie dwóch uporządkowanych list.
Aman
3
@Aman Po prostu wskazuję, że twój kod jest przestarzały. Postępowanie z pocztą zależy od ciebie.
FooBar,
2
@FooBar, typ colsto list; pozwala nawet na duplikaty (które zostaną odrzucone, gdy zostaną użyte w ramce danych). Myślisz o Indexprzedmiotach.
Alexis
8
Oznacza to kopiowanie WSZYSTKICH danych, co jest wysoce nieefektywne. Żałowałem, że pandy nie potrafią tego zrobić bez tworzenia kopii.
Konstantin
440

Możesz także zrobić coś takiego:

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

Możesz uzyskać listę kolumn za pomocą:

cols = list(df.columns.values)

Dane wyjściowe wytworzą:

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

... który następnie można łatwo zmienić ręcznie przed upuszczeniem go do pierwszej funkcji

Freddygv
źródło
8
Możesz także uzyskać listę kolumn z listą (df. Kolumny)
Jim,
8
lubdf.columns.tolist()
Jim
Dla początkujących, takich jak ja, ponownie ułóż listę otrzymaną od kols. Następnie df = df [cols], tj. Zmieniona lista jest upuszczana do pierwszego wyrażenia bez tylko jednego zestawu nawiasów.
Sid
Nazwy kolumn będą liczbami całkowitymi w 3.x df = df[['mean1', 0, 1, 2, 3]]
prosti
1
Nie sądzę, że to dobra odpowiedź, ponieważ nie zawiera kodu, jak zmienić kolejność kolumn w dowolnej ramce danych. Powiedzmy, że importuję plik csv jako pandas pd as pd.read_csv(). Jak można wykorzystać swoją odpowiedź do zmiany kolejności kolumn?
Robvh,
312

Po prostu przypisz nazwy kolumn w żądanej kolejności:

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

Teraz z przodu pojawia się kolumna „średnia”:

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
fixxxer
źródło
6
Czy to robi kopię?
user3226167
20
@NicholasMorley - To nie jest najlepsza odpowiedź, jeśli masz, powiedzmy, 1000 kolumn w swoim pliku.
AGS
1
<df>.columns
Wygląda na
8
To najlepsza odpowiedź dla niewielkiej liczby kolumn.
Dongkyu Choi,
2
To tylko kopia wcześniejszej odpowiedzi @freddygv. To powinna być zaakceptowana odpowiedź, nie ta.
James Hirschorn
134

Co powiesz na:

df.insert(0, 'mean', df.mean(1))

http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion

Wes McKinney
źródło
35
Czy może to być funkcja dodana w przyszłości pandas? coś jak df.move(0,df.mean)?
jason
O rany, to nawet działa tak df_metadata.insert(0,'Db_name',"raw_data")(Kod nie dotyczy tego wątku)
Aetos
3
Piękny. I zdarza się również na miejscu.
cucu8
2
Jest to skalowalne rozwiązanie, ponieważ inne rozwiązania ręcznie wpisują nazwy kolumn.
CKM
Działa to w przypadku pytania PO podczas tworzenia nowej kolumny, ale nie służy do przenoszenia kolumny; próba przeniesienia wyników w*** ValueError: cannot insert mean, already exists
spinup
122

W Twoim przypadku,

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

zrobi dokładnie to, co chcesz.

W moim przypadku (forma ogólna):

df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))
Alvaro Joao
źródło
2
Próbowałem ustawić, copy=Falseale wygląda na to, że reindex_axisnadal tworzy kopię.
Konstantin
1
@Konstantin, czy możesz utworzyć kolejne pytanie dotyczące tego problemu? Lepiej byłoby mieć więcej kontekstu
Alvaro Joao
57

Musisz utworzyć nową listę kolumn w żądanej kolejności, a następnie użyć, df = df[cols]aby zmienić kolejność kolumn w tej nowej kolejności.

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

Możesz także zastosować bardziej ogólne podejście. W tym przykładzie ostatnia kolumna (oznaczona przez -1) jest wstawiana jako pierwsza kolumna.

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

Możesz także użyć tego podejścia do zmiany kolejności kolumn w żądanej kolejności, jeśli są one obecne w ramce danych.

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]
Alexander
źródło
44
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)

Możesz wypróbować następujące rozwiązania:

Rozwiązanie 1:

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

Rozwiązanie 2:


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

Rozwiązanie 3:

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

Rozwiązanie 4:

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

Rozwiązanie 5:

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

rozwiązanie 6:

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

Porównanie czasu:

Rozwiązanie 1:

Czasy procesora: użytkownik 1,05 ms, sys: 35 µs, łącznie: 1,08 ms Czas ściany: 995 µs

Rozwiązanie 2 :

Czasy procesora: użytkownik 933 µs, sys: 0 ns, łącznie: 933 µs Czas ściany: 800 µs

Rozwiązanie 3 :

Czasy procesora: użytkownik 0 ns, sys: 1,35 ms, ogółem: 1,35 ms Czas ściany: 1,08 ms

Rozwiązanie 4 :

Czasy procesora: użytkownik 1,23 ms, sys: 45 µs, łącznie: 1,27 ms Czas ściany: 986 µs

Rozwiązanie 5 :

Czasy procesora: użytkownik 1,09 ms, sys: 19 µs, ogółem: 1,11 ms Czas ściany: 949 µs

Rozwiązanie 6 :

Czasy procesora: użytkownik 955 µs, sys: 34 µs, ogółem: 989 µs Czas ściany: 859 µs

Pygirl
źródło
1
Tak piękna odpowiedź, dziękuję.
qasimalbaqali
1
Rozwiązanie 1 jest tym, czego potrzebowałem, ponieważ mam za dużo kolumn (53), dzięki
ratnesh
@Pygirl która wartość pokazuje rzeczywisty czas zużyty? (użytkownik, sys, całkowity lub czas na ścianie)
sergzemsk
1
To dla mnie najlepsza odpowiedź na problem. Tak wiele rozwiązań (w tym jedno, których potrzebowałem) i proste podejście. Dzięki!
Gustavo Rottgering
1
Rozwiązanie 6 (brak zrozumienia listy):df = df.iloc[:, [1, 2, 3, 0]]
Dmitriy Work
43

Od sierpnia 2018 r .:

Jeśli nazwy kolumn są zbyt długie, aby je wpisać, możesz określić nowe zamówienie za pomocą listy liczb całkowitych z pozycjami:

Dane:

          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

Ogólny przykład:

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

I dla konkretnego przypadku pytania 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

Głównym problemem związanym z tym podejściem jest to, że wielokrotne wywołanie tego samego kodu spowoduje za każdym razem inne wyniki, dlatego należy zachować ostrożność :)

Yuca
źródło
17

Ta funkcja pozwala uniknąć listy wszystkich zmiennych w zbiorze danych, aby zamówić kilka z nich.

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 

Wymaga dwóch argumentów, pierwszy to zestaw danych, drugi to kolumny w zestawie danych, które chcesz przenieść na pierwszy plan.

Tak więc w moim przypadku mam zestaw danych o nazwie Frame ze zmiennymi A1, A2, B1, B2, Total i Date. Jeśli chcę przenieść Total na pierwszy plan, wszystko, co muszę zrobić, to:

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

Jeśli chcę przenieść na początek Total i Date, to:

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

EDYTOWAĆ:

Innym przydatnym sposobem na użycie tego jest, jeśli masz nieznaną tabelę i szukasz zmiennych zawierających określony termin, takich jak VAR1, VAR2, ... możesz wykonać coś takiego:

frame = order(frame,[v for v in frame.columns if "VAR" in v])
seeiespi
źródło
17

Sam wpadłem na podobne pytanie i chciałem tylko dodać to, na czym się zdecydowałem. Podobało mi się reindex_axis() methodzmienianie kolejności kolumn. To działało:

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

Alternatywna metoda oparta na komentarzu @Jorge:

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

Chociaż reindex_axiswydaje się być nieco szybszy w mikro testach niż reindex, myślę, że wolę ten drugi ze względu na jego bezpośredniość.

zegar
źródło
6
To było dobre rozwiązanie, ale reindex_axis będzie przestarzałe. Użyłem reindex i działało dobrze.
Jorge,
15

Po prostu zrób

df = df[['mean'] + df.columns[:-1].tolist()]
Napitupulu Jon
źródło
TypeError: Nie można przekonwertować obiektu „int” na str niejawnie
parvij
interfejs API może ulec zmianie, możesz to również zrobić ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order
Napitupulu Jon
1
Odmiana tego działała dla mnie dobrze. Z istniejącą listą, headersktóra została użyta do stworzenia słownika, który został następnie wykorzystany do utworzenia DataFrame, zadzwoniłem df.reindex(columns=headers). Jedynym problemem, na jaki natknąłem się, było to, co już df.set_index('some header name', inplace=True)wywołałem, więc kiedy reindex został zakończony, dodano kolejną kolumnę o nazwie, some header nameponieważ oryginalna kolumna była teraz indeksem. Jeśli chodzi o składnię określoną powyżej, ['mean'] + df.columnsinterpreter w python daje miIndex(u'meanAddress', u'meanCity', u'meanFirst Name'...
hlongmore
1
@hlongmore: Nie wiem, czy twój poprzedni kod jest, ale edycja powinna działać (przy użyciu 0.19.2)
Napitupulu Jon
Edycja rzeczywiście działa (jestem na 0.20.2). W moim przypadku mam już kolumny, które chcę, więc myślę, że powinienem użyć df.reindex ().
hlongmore
11

Możesz wykonać następujące czynności (pożyczanie części od odpowiedzi Amana):

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

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

df = df[cols]
otteheng
źródło
10

Po prostu wpisz nazwę kolumny, którą chcesz zmienić, i ustaw indeks nowej lokalizacji.

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

W twoim przypadku wyglądałoby to tak:

df = change_column_order(df, 'mean', 0)
ccerhan
źródło
To jest niedoceniane
zelusp
8

Przenoszenie dowolnej kolumny do dowolnej pozycji:

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]
pomber
źródło
7

Myślę, że jest to nieco bardziej zgrabne rozwiązanie:

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

To rozwiązanie jest nieco podobne do rozwiązania @JoeHeffer, ale jest to jedna linijka.

Tutaj usuwamy kolumnę "mean"z ramki danych i dołączamy do indeksu 0o tej samej nazwie kolumny.

erncyp
źródło
5

Oto sposób na przeniesienie jednej istniejącej kolumny, która zmodyfikuje istniejącą ramkę danych.

my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)
Joe Heffer
źródło
5

Pytanie to zostało odebrane przed ale reindex_axis jest przestarzała teraz więc proponuję używać:

df.reindex(sorted(df.columns), axis=1)
dmvianna
źródło
19
Nie, to jest inne. Tam użytkownik chce posortować wszystkie kolumny według nazwy. Tutaj chcą przenieść jedną kolumnę do pierwszej kolumny, pozostawiając kolejność pozostałych kolumn bez zmian.
smci
1
Co jeśli nie chcesz ich sortować?
Chankey Pathak
to zwraca kopię, nie działa w miejscu
spinup
3

Co powiesz na użycie „T”?

df.T.reindex(['mean',0,1,2,3,4]).T
ZEE
źródło
3

@clocker: Twoje rozwiązanie było dla mnie bardzo pomocne, ponieważ chciałem umieścić dwie kolumny z przodu z ramki danych, w której nie znam dokładnie nazw wszystkich kolumn, ponieważ były one wcześniej generowane z instrukcji przestawnej. Tak więc, jeśli znajdujesz się w tej samej sytuacji: Aby przedstawić kolumny z przodu o znanej nazwie, a następnie pozwolić, aby następowały po nich „wszystkie pozostałe kolumny”, opracowałem następujące ogólne rozwiązanie;

df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
Macieja
źródło
3

set():

Stosuje się proste podejście set(), zwłaszcza gdy masz długą listę kolumn i nie chcesz obsługiwać ich ręcznie:

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
Shoresh
źródło
2
Jedna uwaga: kolejność kolumn zniknie, jeśli ustawisz ją w zestawie
pvarma
Ciekawy! @ user1930402 Kilka razy próbowałem powyższego podejścia i nigdy nie miałem żadnych problemów. Jeszcze raz sprawdzę dwukrotnie.
Shoresh,
2

Podobało mi się odpowiedź Shoresha, aby użyć funkcji ustawiania do usuwania kolumn, gdy nie znasz lokalizacji, jednak to nie zadziałało dla mojego celu, ponieważ muszę zachować pierwotną kolejność kolumn (która ma dowolne etykiety kolumn).

Udało mi się to jednak, używając IndexedSet z pakietu boltons.

Musiałem także ponownie dodać wiele etykiet kolumn, więc dla bardziej ogólnego przypadku użyłem następującego kodu:

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

Mam nadzieję, że jest to przydatne dla każdego, kto szuka tego wątku w poszukiwaniu ogólnego rozwiązania.

Jamelade
źródło
Jestem trochę zaskoczony! Używam setdo tego celu dość często i nigdy nie miałem do czynienia z zamówieniami.
Shoresh,
2

Możesz użyć, reindexktórego można użyć dla obu osi:

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
silgon
źródło
2

Oto funkcja pozwalająca to zrobić dla dowolnej liczby kolumn.

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
freeB
źródło
2

Metoda Hackiesta w książce

df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})
Kaustubh J
źródło
2

Myślę, że ta funkcja jest prostsza. Musisz tylko określić podzbiór kolumn na początku lub na końcu albo w obu przypadkach:

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]
Hayj
źródło
1

Uważam, że odpowiedź @ Aman jest najlepsza, jeśli znasz lokalizację drugiej kolumny.

Jeśli nie znasz lokalizacji mean, ale masz tylko jej nazwę, nie możesz bezpośrednio skorzystać z tej opcji cols = cols[-1:] + cols[:-1]. Oto następna najlepsza rzecz, jaką mogłem wymyślić:

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
FooBar
źródło
1

Po prostu przewracanie często pomaga.

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

Lub po prostu przetasuj, aby zobaczyć.

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]
plhn
źródło
0

Większość odpowiedzi nie uogólniała wystarczająco dużo, a metoda reindex_axis w pandach jest nieco żmudna, dlatego oferuję prostą funkcję przeniesienia dowolnej liczby kolumn do dowolnej pozycji za pomocą słownika, w którym klucz = nazwa kolumny i wartość = pozycja, do której należy przejść. Jeśli twoja ramka danych ma dużą wartość True na „big_data”, funkcja zwróci listę uporządkowanych kolumn. I możesz użyć tej listy do podzielenia danych.

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

>>>

wynik

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]
escha
źródło
0

Mam bardzo konkretny przypadek użycia do ponownego zamawiania nazw kolumn w pandach. Czasami tworzę nową kolumnę w ramce danych opartej na istniejącej kolumnie. Domyślnie pandy wstawią moją nową kolumnę na końcu, ale chcę, aby nowa kolumna została wstawiona obok istniejącej kolumny, z której pochodzi.

wprowadź opis zdjęcia tutaj

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)
pk2019
źródło
0

Dość prostym rozwiązaniem, które działało dla mnie, jest użycie .reindex na df.columns:

df=df[df.columns.reindex(['mean',0,1,2,3,4])[0]]
CSQL
źródło