it-swarm.com.de

Wie ändere ich die Reihenfolge der DataFrame-Spalten?

Ich habe das folgende DataFrame (df):

import numpy as np
import pandas as pd

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

Ich füge weitere Spalten durch Zuweisung hinzu:

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

Wie kann ich die Spalte mean nach vorne verschieben, d. H. Als erste Spalte festlegen, wobei die Reihenfolge der anderen Spalten unverändert bleibt?

665
Timmie

Eine einfache Möglichkeit besteht darin, den Datenrahmen mit einer Liste der Spalten neu zuzuweisen, die nach Bedarf neu angeordnet werden.

Das haben Sie jetzt:

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

Ordnen Sie cols nach Ihren Wünschen neu an. So habe ich das letzte Element an die erste Position verschoben:

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

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

Ordnen Sie dann den Datenrahmen wie folgt neu:

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
691
Aman

Sie könnten auch so etwas tun:

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

Sie können die Liste der Spalten erhalten mit:

cols = list(df.columns.values)

Die Ausgabe erzeugt:

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

... die dann einfach manuell neu angeordnet werden kann, bevor sie in die erste Funktion abgelegt wird

331
freddygv

Ordnen Sie einfach die Spaltennamen in der gewünschten Reihenfolge zu:

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

Nun kommt vorne die Spalte 'mean' heraus:

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
280
fixxxer
112
Wes McKinney

In deinem Fall,

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

wird genau das tun, was Sie wollen.

In meinem Fall (allgemeine Form):

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

Ab August 2018:

Wenn Ihre Spaltennamen zu lang für die Eingabe sind, können Sie die neue Reihenfolge über eine Liste von Ganzzahlen mit den Positionen angeben:

Daten:

          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

Allgemeines Beispiel:

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

Und für den speziellen Fall der OP-Frage:

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

Das Hauptproblem bei diesem Ansatz ist, dass das mehrmalige Aufrufen desselben Codes jedes Mal zu unterschiedlichen Ergebnissen führt. Man muss also vorsichtig sein :)

35
Yuca

Sie müssen eine neue Liste Ihrer Spalten in der gewünschten Reihenfolge erstellen und dann mit df = df[cols] die Spalten in dieser neuen Reihenfolge neu anordnen.

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

Sie können auch einen allgemeineren Ansatz verwenden. In diesem Beispiel wird die letzte Spalte (angegeben durch -1) als erste Spalte eingefügt.

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

Sie können diesen Ansatz auch verwenden, um Spalten in einer gewünschten Reihenfolge neu anzuordnen, wenn sie im DataFrame vorhanden sind.

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

Ich bin selbst auf eine ähnliche Frage gestoßen und wollte nur hinzufügen, worauf ich mich eingelassen habe. Ich mochte die reindex_axis() method zum Ändern der Spaltenreihenfolge. Das hat funktioniert:

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

Eine alternative Methode basierend auf dem Kommentar von @Jorge:

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

Obwohl reindex_axis in Mikro-Benchmarks etwas schneller zu sein scheint als reindex, glaube ich, dass ich letzteres wegen seiner Direktheit bevorzuge.

16
clocker

Einfach machen,

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

Diese Funktion vermeidet, dass Sie jede Variable in Ihrem Datensatz auflisten müssen, um nur einige davon zu bestellen.

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 

Es werden zwei Argumente benötigt, das erste ist das Dataset, das zweite sind die Spalten im Dataset, die Sie in den Vordergrund stellen möchten.

In meinem Fall habe ich also einen Datensatz namens Frame mit den Variablen A1, A2, B1, B2, Total und Date. Wenn ich Total nach vorne bringen möchte, muss ich nur Folgendes tun:

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

Wenn ich Total und Date in den Vordergrund stellen möchte, mache ich Folgendes:

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

BEARBEITEN:

Eine weitere nützliche Möglichkeit, dies zu verwenden, ist, wenn Sie eine unbekannte Tabelle haben und nach Variablen mit einem bestimmten Begriff suchen, z. B. VAR1, VAR2, ..., können Sie Folgendes ausführen:

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

Sie könnten Folgendes tun (Teile aus Amans Antwort ausleihen):

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

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

df = df[cols]
11
otteheng

Geben Sie einfach den Spaltennamen ein, den Sie ändern möchten, und legen Sie den Index für den neuen Speicherort fest.

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

Für Ihren Fall wäre dies wie folgt:

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

Verschieben einer Spalte an eine beliebige Position:

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
pomber

Am einfachsten wäre es, die Reihenfolge der Spaltennamen wie folgt zu ändern

df = df[['mean', Col1,Col2,Col3]]

7
Gayatri

Diese Frage wurde bereits beantwortet vor aber reindex_axis ist jetzt veraltet, daher würde ich vorschlagen:

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

set():

Ein einfacher Ansatz ist set(), insbesondere wenn Sie eine lange Liste von Spalten haben und diese nicht manuell bearbeiten möchten:

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

Hier ist eine Möglichkeit, eine vorhandene Spalte zu verschieben, um den vorhandenen Datenrahmen zu ändern.

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

Wie wäre es mit "T"?

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

Ich habe die Funktion insert() ausprobiert, wie von Wes McKinney vorgeschlagen.

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

Dies führte zu dem Ergebnis, dass Timmie in einer Zeile wollte, ohne dass die letzte Spalte verschoben werden musste.

3
Gan William

@clocker: Ihre Lösung war für mich sehr hilfreich, da ich zwei Spalten aus einem Datenframe heraus nach vorne bringen wollte, wobei ich nicht genau die Namen aller Spalten kenne, da diese zuvor aus einer Pivot-Anweisung generiert wurden. Wenn Sie sich also in der gleichen Situation befinden: Um Spalten, deren Namen Sie kennen, in den Vordergrund zu stellen und sie dann "alle anderen Spalten" folgen zu lassen, habe ich die folgende allgemeine Lösung gefunden.

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

Sie können reindex verwenden, das für beide Achsen verwendet werden kann:

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
silgon

Hier ist eine Funktion, um dies für eine beliebige Anzahl von Spalten zu tun.

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
freeB

DataFrame.sort_index(axis=1) ist ziemlich sauber . Dokument hier prüfen . Und dann concat

1
Shihe Zhang

Die hackigste Methode im Buch

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

Ich glaube @ Amans Antwort ist das Beste, wenn Sie den Ort der anderen Spalte kennen.

Wenn Sie den Speicherort von mean nicht kennen, aber nur den Namen haben, können Sie nicht direkt auf cols = cols[-1:] + cols[:-1] zurückgreifen. Folgendes ist das Nächstbeste, was ich mir einfallen lassen könnte:

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
FooBar

Ich mochte Shoreshs Antwort die Set-Funktion zum Entfernen von Spalten verwenden, wenn Sie den Speicherort nicht kennen. Dies funktionierte jedoch nicht für meinen Zweck, da ich die ursprüngliche Spaltenreihenfolge (die eine beliebige Spalte enthält) beibehalten musste Etiketten).

Ich habe dies funktioniert, indem ich IndexedSet aus dem boltons-Paket verwendet habe.

Ich musste auch mehrere Spaltenbeschriftungen erneut hinzufügen. In einem allgemeineren Fall habe ich den folgenden Code verwendet:

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

Hoffe, dies ist nützlich für alle, die in diesem Thread nach einer allgemeinen Lösung suchen.

1
Jamelade