Как изменить порядок столбцов DataFrame?

У меня есть следующее DataFrame (df):

import numpy as np
import pandas as pd

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

Я добавляю больше столбцов по заданию:

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

Как я могу переместить колонку mean на передний план, то есть установить его в качестве первого столбца, оставив порядок остальных столбцов нетронутым?

44 ответа

Одним простым способом было бы переназначить фрейм данных со списком столбцов, переставленных по мере необходимости.

Это то, что у вас есть сейчас:

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

перестраивать cols любым способом, который вы хотите. Вот как я переместил последний элемент на первую позицию:

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

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

Затем измените порядок данных таким образом:

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

Вы также можете сделать что-то вроде этого:

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

Вы можете получить список столбцов с:

cols = list(df.columns.values)

Выход будет производить:

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

... который затем легко переставить вручную, прежде чем поместить его в первую функцию

Просто присвойте имена столбцов в том порядке, в котором они вам нужны:

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

Теперь "средняя" колонка выходит впереди:

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

Как насчет:

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

http://pandas.pydata.org/pandas-docs/stable/dsintro.html

В твоем случае,

df = df.reindex_axis(['mean',0,1,2,3,4], axis=1)

будет делать именно то, что вы хотите.

В моем случае (общая форма):

df = df.reindex_axis(sorted(df.columns), axis=1)
df = df.reindex_axis(['opened'] + list([a for a in df.columns if a != 'opened']), axis=1)

обновление январь 2018

Если вы хотите использовать reindex :

df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))
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)

Вы можете попробовать следующие решения:

Решение 1:

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

Решение 2:


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

Решение 3:

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

Решение 4:

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

Решение 5:

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

решение 6:

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

Сравнение времени:

Решение 1:

Время ЦП: пользовательское 1,05 мс, системное: 35 мкс, всего: 1,08 мс Время на стене: 995 мкс

Решение 2:

Время ЦП: пользовательское 933 мкс, системное: 0 нс, общее: 933 мкс Время на стене: 800 мкс

Решение 3:

Время ЦП: пользовательский 0 нс, системный: 1,35 мс, всего: 1,35 мс Время на стене: 1,08 мс

Решение 4:

Время ЦП: пользовательское 1,23 мс, системное: 45 мкс, всего: 1,27 мс Время на стене: 986 мкс

Решение 5:

Время ЦП: пользовательское 1,09 мс, системное: 19 мкс, всего: 1,11 мс Время на стене: 949 мкс

Решение 6:

Время ЦП: пользовательское 955 мкс, системное: 34 мкс, всего: 989 мкс Время на стене: 859 мкс

Вам нужно создать новый список ваших столбцов в нужном порядке, а затем использовать df = df[cols] переставить столбцы в этом новом порядке.

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

Вы также можете использовать более общий подход. В этом примере последний столбец (обозначенный -1) вставляется как первый столбец.

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

Вы также можете использовать этот подход для переупорядочения столбцов в желаемом порядке, если они присутствуют в DataFrame.

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]

Самый простой способ. Предположим, у вас есть df с колоннами A B Cты можешь просто df.reindex(['B','C','A'],axis=1)

На этот вопрос уже был дан ответ, но reindex_axis устарел, поэтому я бы предложил использовать:

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

С августа 2018 года:

Если имена ваших столбцов слишком длинные для ввода, вы можете указать новый порядок через список целых чисел с позициями:

new_order = [3,2,1,4,5,0]
df = df[df.columns[new_order]]
print(df)  

        a         c         b      mean         d         e
0  0.637589  0.634264  0.733961  0.617316  0.534911  0.545856
1  0.854449  0.830046  0.883416  0.678389  0.183003  0.641032
2  0.332996  0.195891  0.879472  0.545261  0.447813  0.870135
3  0.902704  0.843252  0.348227  0.677614  0.635780  0.658107
4  0.422357  0.529151  0.619282  0.412559  0.405749  0.086255
5  0.251454  0.940245  0.068633  0.554269  0.691631  0.819380
6  0.423781  0.179961  0.643971  0.361245  0.105050  0.453460
7  0.680696  0.487651  0.255453  0.419046  0.330417  0.341014
8  0.276729  0.473765  0.981271  0.690007  0.817877  0.900394
9  0.964470  0.248088  0.609391  0.463661  0.128077  0.368279

А для конкретного случая вопроса ОП:

new_order = [-1,0,1,2,3,4]
df = df[df.columns[new_order]]
print(df)

      mean         a         b         c         d         e
0  0.595177  0.329206  0.713246  0.712898  0.572263  0.648273
1  0.638860  0.452519  0.598171  0.797982  0.858137  0.487490
2  0.287636  0.100442  0.244445  0.288450  0.285795  0.519049
3  0.653974  0.863342  0.460811  0.782644  0.827890  0.335183
4  0.285233  0.004613  0.485135  0.014066  0.489957  0.432394
5  0.430761  0.630070  0.328865  0.528100  0.031827  0.634943
6  0.444338  0.102679  0.808613  0.389616  0.440022  0.480759
7  0.536163  0.063105  0.420832  0.959125  0.643879  0.593874
8  0.556107  0.716114  0.180603  0.668684  0.262900  0.952237
9  0.416280  0.816816  0.064956  0.178113  0.377693  0.643820

Вы можете изменить порядок столбцов фрейма данных, используя список имен с:

df = df.filter(list_of_col_names)

Думаю, это чуть более аккуратное решение:

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

Это решение чем-то похоже на решение @JoeHeffer, но это один лайнер.

Здесь убираем столбик "mean" из фрейма данных и прикрепите его к индексу 0 с тем же именем столбца.

Я сам столкнулся с похожим вопросом и просто хотел добавить то, на чем остановился. Мне понравилось reindex_axis() method для изменения порядка столбцов. Это сработало:

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

Альтернативный метод, основанный на комментарии @Jorge:

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

Хотя reindex_axis кажется, немного быстрее в микро тестах, чем reindexЯ думаю, что предпочитаю последнее за его прямоту.

Вот способ переместить один существующий столбец, который изменит существующий фрейм данных на месте.

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

Эта функция избавляет вас от необходимости перечислять каждую переменную в вашем наборе данных, чтобы упорядочить несколько из них.

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 

Он принимает два аргумента: первый - это набор данных, второй - столбцы в наборе данных, которые вы хотите вывести на передний план.

Так что в моем случае у меня есть набор данных с именем Frame с переменными A1, A2, B1, B2, Total и Date. Если я хочу вывести Total на фронт, все, что мне нужно сделать, это:

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

Если я хочу вывести Total и Date на первый план, тогда я делаю:

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

РЕДАКТИРОВАТЬ:

Другой полезный способ использовать это, если у вас есть незнакомая таблица и вы ищете переменные с определенным термином в них, например, VAR1, VAR2,... вы можете выполнить что-то вроде:

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

Просто сделай,

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

Просто введите имя столбца, который вы хотите изменить, и установите индекс для нового местоположения.

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

Для вашего случая это будет выглядеть так:

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

Вы могли бы сделать следующее (заимствуя части из ответа Амана):

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

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

df = df[cols]

Перемещение любого столбца в любую позицию:

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]

@clocker: Ваше решение было очень полезным для меня, так как я хотел вывести два столбца вперед из кадра данных, где я не знаю точно имена всех столбцов, потому что они были сгенерированы из сводной инструкции ранее. Итак, если вы находитесь в той же ситуации: чтобы вывести перед собой столбцы, имена которых вы знаете, а затем позволить им следовать "все остальные столбцы", я пришел к следующему общему решению;

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

Вот очень простой ответ на это (всего одна строчка).

Вы можете сделать это после добавления столбца "n" в свой df следующим образом.

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))
df['mean'] = df.mean(1)
df
           0           1           2           3           4        mean
0   0.929616    0.316376    0.183919    0.204560    0.567725    0.440439
1   0.595545    0.964515    0.653177    0.748907    0.653570    0.723143
2   0.747715    0.961307    0.008388    0.106444    0.298704    0.424512
3   0.656411    0.809813    0.872176    0.964648    0.723685    0.805347
4   0.642475    0.717454    0.467599    0.325585    0.439645    0.518551
5   0.729689    0.994015    0.676874    0.790823    0.170914    0.672463
6   0.026849    0.800370    0.903723    0.024676    0.491747    0.449473
7   0.526255    0.596366    0.051958    0.895090    0.728266    0.559587
8   0.818350    0.500223    0.810189    0.095969    0.218950    0.488736
9   0.258719    0.468106    0.459373    0.709510    0.178053    0.414752


### here you can add below line and it should work 
# Don't forget the two (()) 'brackets' around columns names.Otherwise, it'll give you an error.

df = df[list(('mean',0, 1, 2,3,4))]
df

        mean           0           1           2           3           4
0   0.440439    0.929616    0.316376    0.183919    0.204560    0.567725
1   0.723143    0.595545    0.964515    0.653177    0.748907    0.653570
2   0.424512    0.747715    0.961307    0.008388    0.106444    0.298704
3   0.805347    0.656411    0.809813    0.872176    0.964648    0.723685
4   0.518551    0.642475    0.717454    0.467599    0.325585    0.439645
5   0.672463    0.729689    0.994015    0.676874    0.790823    0.170914
6   0.449473    0.026849    0.800370    0.903723    0.024676    0.491747
7   0.559587    0.526255    0.596366    0.051958    0.895090    0.728266
8   0.488736    0.818350    0.500223    0.810189    0.095969    0.218950
9   0.414752    0.258719    0.468106    0.459373    0.709510    0.178053

Вы можете использовать набор, который представляет собой неупорядоченную коллекцию уникальных элементов, чтобы сохранить "порядок других столбцов нетронутым":

other_columns = list(set(df.columns).difference(["mean"])) #[0, 1, 2, 3, 4]

Затем вы можете использовать лямбду, чтобы переместить определенный столбец на передний план:

In [1]: import numpy as np                                                                               

In [2]: import pandas as pd                                                                              

In [3]: df = pd.DataFrame(np.random.rand(10, 5))                                                         

In [4]: df["mean"] = df.mean(1)                                                                          

In [5]: move_col_to_front = lambda df, col: df[[col]+list(set(df.columns).difference([col]))]            

In [6]: move_col_to_front(df, "mean")                                                                    
Out[6]: 
       mean         0         1         2         3         4
0  0.697253  0.600377  0.464852  0.938360  0.945293  0.537384
1  0.609213  0.703387  0.096176  0.971407  0.955666  0.319429
2  0.561261  0.791842  0.302573  0.662365  0.728368  0.321158
3  0.518720  0.710443  0.504060  0.663423  0.208756  0.506916
4  0.616316  0.665932  0.794385  0.163000  0.664265  0.793995
5  0.519757  0.585462  0.653995  0.338893  0.714782  0.305654
6  0.532584  0.434472  0.283501  0.633156  0.317520  0.994271
7  0.640571  0.732680  0.187151  0.937983  0.921097  0.423945
8  0.562447  0.790987  0.200080  0.317812  0.641340  0.862018
9  0.563092  0.811533  0.662709  0.396048  0.596528  0.348642

In [7]: move_col_to_front(df, 2)                                                                         
Out[7]: 
          2         0         1         3         4      mean
0  0.938360  0.600377  0.464852  0.945293  0.537384  0.697253
1  0.971407  0.703387  0.096176  0.955666  0.319429  0.609213
2  0.662365  0.791842  0.302573  0.728368  0.321158  0.561261
3  0.663423  0.710443  0.504060  0.208756  0.506916  0.518720
4  0.163000  0.665932  0.794385  0.664265  0.793995  0.616316
5  0.338893  0.585462  0.653995  0.714782  0.305654  0.519757
6  0.633156  0.434472  0.283501  0.317520  0.994271  0.532584
7  0.937983  0.732680  0.187151  0.921097  0.423945  0.640571
8  0.317812  0.790987  0.200080  0.641340  0.862018  0.562447
9  0.396048  0.811533  0.662709  0.596528  0.348642  0.563092

Самый простой способ - изменить порядок имен столбцов следующим образом.

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

Довольно простое решение, которое сработало для меня, - использовать.reindex в df.columns:

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

Часто помогает просто перелистывание.

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

Или просто перетасуйте, чтобы посмотреть.

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]

Самый хакерский метод в книге

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

Как насчет использования "T"?

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

Ты можешь использовать reindex который можно использовать для обеих осей:

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

Вот функция, которая делает это для любого количества столбцов.

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

Вот пример очень простого способа сделать это. Если вы копируете заголовки из Excel, используйте .split('\t')

      df = df['FILE_NAME DISPLAY_PATH SHAREPOINT_PATH RETAILER LAST_UPDATE'.split()]
Другие вопросы по тегам