Verschieben Sie die Spalte nach Namen in Pandas an die Vorderseite der Tabelle


89

Hier ist mein df:

                             Net   Upper   Lower  Mid  Zsore
Answer option                                                
More than once a day          0%   0.22%  -0.12%   2    65 
Once a day                    0%   0.32%  -0.19%   3    45
Several times a week          2%   2.45%   1.10%   4    78
Once a week                   1%   1.63%  -0.40%   6    65

Wie kann ich eine Spalte mit dem Namen ( "Mid") an den Anfang der Tabelle, Index 0, verschieben? So sollte das Ergebnis aussehen:

                             Mid   Upper   Lower  Net  Zsore
Answer option                                                
More than once a day          2   0.22%  -0.12%   0%    65 
Once a day                    3   0.32%  -0.19%   0%    45
Several times a week          4   2.45%   1.10%   2%    78
Once a week                   6   1.63%  -0.40%   1%    65

Mein aktueller Code verschiebt die Spalte nach Index mit, df.columns.tolist()aber ich möchte sie nach Namen verschieben.

Antworten:


106

Wir können verwenden, ixum neu zu ordnen, indem wir eine Liste übergeben:

In [27]:
# get a list of columns
cols = list(df)
# move the column to head of list using index, pop and insert
cols.insert(0, cols.pop(cols.index('Mid')))
cols
Out[27]:
['Mid', 'Net', 'Upper', 'Lower', 'Zsore']
In [28]:
# use ix to reorder
df = df.ix[:, cols]
df
Out[28]:
                      Mid Net  Upper   Lower  Zsore
Answer_option                                      
More_than_once_a_day    2  0%  0.22%  -0.12%     65
Once_a_day              3  0%  0.32%  -0.19%     45
Several_times_a_week    4  2%  2.45%   1.10%     78
Once_a_week             6  1%  1.63%  -0.40%     65

Eine andere Methode besteht darin, einen Verweis auf die Spalte zu nehmen und sie vorne wieder einzufügen:

In [39]:
mid = df['Mid']
df.drop(labels=['Mid'], axis=1,inplace = True)
df.insert(0, 'Mid', mid)
df
Out[39]:
                      Mid Net  Upper   Lower  Zsore
Answer_option                                      
More_than_once_a_day    2  0%  0.22%  -0.12%     65
Once_a_day              3  0%  0.32%  -0.19%     45
Several_times_a_week    4  2%  2.45%   1.10%     78
Once_a_week             6  1%  1.63%  -0.40%     65

Sie können auch locdas gleiche Ergebnis erzielen, das ixin einer zukünftigen Version von Pandas von veraltet sein wird0.20.0 wird:

df = df.loc[:, cols]

45

Sie können die Funktion df.reindex () in Pandas verwenden. df ist

                      Net  Upper   Lower  Mid  Zsore
Answer option                                      
More than once a day  0%  0.22%  -0.12%    2     65
Once a day            0%  0.32%  -0.19%    3     45
Several times a week  2%  2.45%   1.10%    4     78
Once a week           1%  1.63%  -0.40%    6     65

Definieren Sie eine Liste mit Spaltennamen

cols = df.columns.tolist()
cols
Out[13]: ['Net', 'Upper', 'Lower', 'Mid', 'Zsore']

Verschieben Sie den Spaltennamen an eine beliebige Stelle

cols.insert(0, cols.pop(cols.index('Mid')))
cols
Out[16]: ['Mid', 'Net', 'Upper', 'Lower', 'Zsore']

Verwenden Sie dann die df.reindex()Funktion, um neu zu ordnen

df = df.reindex(columns= cols)

Ausgabe ist: df

                      Mid  Upper   Lower Net  Zsore
Answer option                                      
More than once a day    2  0.22%  -0.12%  0%     65
Once a day              3  0.32%  -0.19%  0%     45
Several times a week    4  2.45%   1.10%  2%     78
Once a week             6  1.63%  -0.40%  1%     65

44

Vielleicht fehlt mir etwas, aber viele dieser Antworten scheinen zu kompliziert. Sie sollten nur die Spalten in einer einzigen Liste festlegen können:

Spalte nach vorne:

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

Oder wenn Sie es stattdessen nach hinten verschieben möchten:

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

Oder wenn Sie mehr als eine Spalte verschieben möchten:

cols_to_move = ['Mid', 'Zsore']
df           = df[ cols_to_move + [ col for col in df.columns if col not in cols_to_move ] ]

22

Ich bevorzuge diese Lösung:

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

Es ist einfacher zu lesen und schneller als andere vorgeschlagene Antworten.

def move_column_inplace(df, col, pos):
    col = df.pop(col)
    df.insert(pos, col.name, col)

Leistungsbewertung:

Bei diesem Test wird die aktuell letzte Spalte bei jeder Wiederholung nach vorne verschoben. In-Place-Methoden weisen im Allgemeinen eine bessere Leistung auf. Während die Lösung von citynorman direkt umgesetzt werden kann, kann die Methode von Ed Chum und die Methode von .locsachinnm reindexnicht.

Während andere Methoden generisch sind, beschränkt sich die Lösung von citynorman auf pos=0. Ich habe keinen Leistungsunterschied zwischen df.loc[cols]und festgestellt df[cols], weshalb ich einige andere Vorschläge nicht aufgenommen habe.

Ich habe mit Python 3.6.8 und Pandas 0.24.2 auf einem MacBook Pro getestet (Mitte 2015).

import numpy as np
import pandas as pd

n_cols = 11
df = pd.DataFrame(np.random.randn(200000, n_cols),
                  columns=range(n_cols))

def move_column_inplace(df, col, pos):
    col = df.pop(col)
    df.insert(pos, col.name, col)

def move_to_front_normanius_inplace(df, col):
    move_column_inplace(df, col, 0)
    return df

def move_to_front_chum(df, col):
    cols = list(df)
    cols.insert(0, cols.pop(cols.index(col)))
    return df.loc[:, cols]

def move_to_front_chum_inplace(df, col):
    col = df[col]
    df.drop(col.name, axis=1, inplace=True)
    df.insert(0, col.name, col)
    return df

def move_to_front_elpastor(df, col):
    cols = [col] + [ c for c in df.columns if c!=col ]
    return df[cols] # or df.loc[cols]

def move_to_front_sachinmm(df, col):
    cols = df.columns.tolist()
    cols.insert(0, cols.pop(cols.index(col)))
    df = df.reindex(columns=cols, copy=False)
    return df

def move_to_front_citynorman_inplace(df, col):
    # This approach exploits that reset_index() moves the index
    # at the first position of the data frame.
    df.set_index(col, inplace=True)
    df.reset_index(inplace=True)
    return df

def test(method, df):
    col = np.random.randint(0, n_cols)
    method(df, col)

col = np.random.randint(0, n_cols)
ret_mine = move_to_front_normanius_inplace(df.copy(), col)
ret_chum1 = move_to_front_chum(df.copy(), col)
ret_chum2 = move_to_front_chum_inplace(df.copy(), col)
ret_elpas = move_to_front_elpastor(df.copy(), col)
ret_sach = move_to_front_sachinmm(df.copy(), col)
ret_city = move_to_front_citynorman_inplace(df.copy(), col)

# Assert equivalence of solutions.
assert(ret_mine.equals(ret_chum1))
assert(ret_mine.equals(ret_chum2))
assert(ret_mine.equals(ret_elpas))
assert(ret_mine.equals(ret_sach))
assert(ret_mine.equals(ret_city))

Ergebnisse :

# For n_cols = 11:
%timeit test(move_to_front_normanius_inplace, df)
# 1.05 ms ± 42.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit test(move_to_front_citynorman_inplace, df)
# 1.68 ms ± 46.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit test(move_to_front_sachinmm, df)
# 3.24 ms ± 96.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_chum, df)
# 3.84 ms ± 114 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_elpastor, df)
# 3.85 ms ± 58.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_chum_inplace, df)
# 9.67 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


# For n_cols = 31:
%timeit test(move_to_front_normanius_inplace, df)
# 1.26 ms ± 31.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_citynorman_inplace, df)
# 1.95 ms ± 260 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_sachinmm, df)
# 10.7 ms ± 348 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_chum, df)
# 11.5 ms ± 869 µs per loop (mean ± std. dev. of 7 runs, 100 loops each
%timeit test(move_to_front_elpastor, df)
# 11.4 ms ± 598 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(move_to_front_chum_inplace, df)
# 31.4 ms ± 1.89 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

1
Tolle Lösung. Wir sollten die geänderte df mit der eingefügten Spalte jedoch nicht explizit der ursprünglichen df zuweisen. Also df = df.insert(0, col.name, col)müssen wir stattdessen tun df.insert(0, col.name, col). Sie haben es aber richtig in der Funktion move_column_inplace().
Melihozbek

1
Danke @normanius. Ich habe hart in Dexters Labor gearbeitet. :-) Tolle Lösung. Ockhams Rasiermesser. Einfach und elegant.
Brohjoe

Ich bevorzuge auch diese Lösung :)
user88484

18

Mir hat nicht gefallen, wie ich alle anderen Spalten in den anderen Lösungen explizit angeben musste, daher funktionierte dies am besten für mich. Obwohl es für große Datenrahmen langsam sein könnte ...?

df = df.set_index('Mid').reset_index()


Dies nutzt die aktuellen Versionen aus, reset_index()um den abgelegten Index an der ersten Position einzufügen. Beachten Sie jedoch, dass dieses Verhalten in den Dokumenten nicht angegeben ist .
Normanius

1
Bezüglich der Aufführung siehe meine Antwort. Es ist vorteilhaft inplace=Truefür beide set_index()und zu verwenden reset_index().
Normanius

9

Hier ist ein allgemeiner Satz von Code, den ich häufig verwende, um die Position von Spalten neu zu ordnen. Sie können es nützlich finden.

cols = df.columns.tolist()
n = int(cols.index('Mid'))
cols = [cols[n]] + cols[:n] + cols[n+1:]
df = df[cols]

3
Erklären Sie im Idealfall Ihre Antwort und was sie zu einer guten Lösung macht, und veröffentlichen Sie nicht nur einen Code. Sie riskieren Downvoting
Tjebo

5

Um die Zeilen eines DataFrame neu anzuordnen, verwenden Sie einfach eine Liste wie folgt.

df = df[['Mid', 'Net', 'Upper', 'Lower', 'Zsore']]

Dies macht sehr deutlich, was beim späteren Lesen des Codes getan wurde. Auch verwenden:

df.columns
Out[1]: Index(['Net', 'Upper', 'Lower', 'Mid', 'Zsore'], dtype='object')

Dann ausschneiden und zur Neuordnung einfügen.


Speichern Sie für einen DataFrame mit vielen Spalten die Liste der Spalten in einer Variablen und fügen Sie die gewünschte Spalte an den Anfang der Liste. Hier ist ein Beispiel:

cols = [str(col_name) for col_name in range(1001)]
data = np.random.rand(10,1001)
df = pd.DataFrame(data=data, columns=cols)

mv_col = cols.pop(cols.index('77'))
df = df[[mv_col] + cols]

Jetzt df.columnshat.

Index(['77', '0', '1', '2', '3', '4', '5', '6', '7', '8',
       ...
       '991', '992', '993', '994', '995', '996', '997', '998', '999', '1000'],
      dtype='object', length=1001)

Was ist, wenn Sie mit einem DataFrame arbeiten, der aus 1001 Spalten besteht?
Normanius

Das Konzept ist das gleiche, jedoch sollten bei vielen Spalten die Spalten in einer Liste gespeichert und die Liste bearbeitet werden. Ein Beispiel finden Sie oben in meinen Änderungen. Mein Beispiel ist praktisch dasselbe wie stackoverflow.com/a/51009742/5827921 .
Dustin Helliwell

0

Hier ist eine sehr einfache Antwort darauf.

Vergessen Sie nicht die zwei (()) 'Klammern' um die Spaltennamen. Andernfalls erhalten Sie einen Fehler.


# here you can add below line and it should work 
df = df[list(('Mid','Upper', 'Lower', 'Net','Zsore'))]
df

                             Mid   Upper   Lower  Net  Zsore
Answer option                                                
More than once a day          2   0.22%  -0.12%   0%    65 
Once a day                    3   0.32%  -0.19%   0%    45
Several times a week          4   2.45%   1.10%   2%    78
Once a week                   6   1.63%  -0.40%   1%    65

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.