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?
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
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
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
Wie wäre es mit:
df.insert(0, 'mean', df.mean(1))
http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion
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']) ))
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 :)
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]
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.
Einfach machen,
df = df[['mean'] + df.columns[:-1].tolist()]
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])
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]
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)
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]
Am einfachsten wäre es, die Reihenfolge der Spaltennamen wie folgt zu ändern
df = df[['mean', Col1,Col2,Col3]]
Diese Frage wurde bereits beantwortet vor aber reindex_axis ist jetzt veraltet, daher würde ich vorschlagen:
df.reindex(sorted(df.columns), axis=1)
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]
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)
Wie wäre es mit "T"?
df.T.reindex(['mean',0,1,2,3,4]).T
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.
@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)
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
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
DataFrame.sort_index(axis=1)
ist ziemlich sauber . Dokument hier prüfen . Und dann concat
Die hackigste Methode im Buch
df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})
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
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.