Verplaats kolom op naam naar voorkant van tabel in panda’s

Hier is mijn 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

Hoe kan ik een kolom op naam ("Mid") naar de voorkant van de tabel, index 0, verplaatsen. Zo zou het resultaat eruit moeten zien:

                            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

Mijn huidige code verplaatst de kolom per index met behulp van df.columns.tolist()maar ik zou deze graag op naam willen verplaatsen.


Antwoord 1, autoriteit 100%

We kunnen ixgebruiken om opnieuw te ordenen door een lijst door te geven:

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

Een andere methode is om een ​​verwijzing naar de kolom te nemen en deze vooraan opnieuw in te voegen:

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

Je kunt ook locgebruiken om hetzelfde resultaat te bereiken, aangezien ixzal worden beëindigd in een toekomstige versie van panda’s van 0.20.0en verder:

df = df.loc[:, cols]

Antwoord 2, autoriteit 74%

Misschien mis ik iets, maar veel van deze antwoorden lijken te ingewikkeld. Je zou in staat moeten zijn om de kolommen in een enkele lijst in te stellen:

Kolom naar voren:

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

Of als u het in plaats daarvan naar achteren wilt verplaatsen:

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

Of als u meer dan één kolom wilt verplaatsen:

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

Antwoord 3, autoriteit 44%

Ik geef de voorkeur aan deze oplossing:

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

Het is eenvoudiger te lezen en sneller dan andere voorgestelde antwoorden.

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

Prestatiebeoordeling:

Voor deze test wordt de momenteel laatste kolom bij elke herhaling naar voren verplaatst. In-place methoden presteren over het algemeen beter. Hoewel de oplossing van citynorman ter plekke kan worden gemaakt, kunnen de methode van Ed Chum op basis van .locen de methode van sachinnm op basis van reindexdat niet.

Hoewel andere methoden generiek zijn, is de oplossing van citynorman beperkt tot pos=0. Ik heb geen prestatieverschil waargenomen tussen df.loc[cols]en df[cols], daarom heb ik geen enkele andere suggesties toegevoegd.

Ik heb getest met python 3.6.8 en panda’s 0.24.2 op een MacBook Pro (medio 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))

Resultaten:

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

Antwoord 4, autoriteit 37%

Je kunt de functie df.reindex() gebruiken in panda’s.
df is

                            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

definieer een lijst met kolomnamen

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

verplaats de kolomnaam naar waar u maar wilt

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

gebruik vervolgens de functie df.reindex()om opnieuw te ordenen

df = df.reindex(columns= cols)

uitvoer is: 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

Antwoord 5, autoriteit 16%

Ik vond het niet leuk dat ik alle andere kolommen in de andere oplossingen expliciet moest specificeren, dus dit werkte het beste voor mij. Hoewel het misschien traag is voor grote dataframes…?

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

BEWERKEN:
Een andere oplossing die sneller en flexibeler is

cfg_col_sel = ['Mid', 'Zscore']
cfg_col_sel = cfg_col_sel+[s for s in df.columns if not s in cfg_col_sel]
df = df[cfg_col_sel]

Antwoord 6, autoriteit 7%

Hier is een algemene set code die ik vaak gebruik om de positie van kolommen te herschikken. Misschien vind je het handig.

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

Antwoord 7, autoriteit 4%

Gebruik een lijst als volgt om de rijen van een DataFrame opnieuw te ordenen.

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

Dit maakt het heel duidelijk wat er is gedaan bij het later lezen van de code. Gebruik ook:

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

Vervolgens knippen en plakken om opnieuw te ordenen.


Voor een DataFrame met veel kolommen slaat u de lijst met kolommen op in een variabele en plaatst u de gewenste kolom vooraan in de lijst. Hier is een voorbeeld:

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]

Nu heeft df.columns.

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)

Antwoord 8, autoriteit 2%

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

lijkt een vrij gemakkelijke manier om dit te doen.


Antwoord 9

Als u een kolom naar de voorkant van het gegevensframe wilt verplaatsene, kunt u
gebruik set_index().

df.set_index(df.pop('column_name'), inplace=True)
df.reset_index(inplace=True)


U moet eerst de kolom instellen die u naar voren wilt brengen als de index van het dataframe (en wij doen een popom de kolom uit de originele dataframe te laten vallen voordat u het instelt De index om een ​​naambotsing in de volgende actie te vermijden) en uiteindelijk belt u reset_index()om de oude index de eerste kolom van het dataframe te maken.


Zie voor meer informatie hoe Om de volgorde van dataframe-kolommen in Panda’s te wijzigen.

Other episodes