Как изменить порядок столбцов 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 в начало, т.е. установить его как первый столбец, оставляя порядок остальных столбцов нетронутым?

Ответ 1

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

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

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

Ответ 2

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

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

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

cols = list(df.columns.values)

Выход будет выдавать:

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

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

Ответ 3

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

Данные:

          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

Общий пример:

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

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

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

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

Ответ 7

Вам нужно создать новый список столбцов в нужном порядке, а затем использовать 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]

Ответ 8

Я сам столкнулся с подобным вопросом и просто хотел добавить то, на что я остановился. Мне понравился метод 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, я думаю, что я предпочитаю последнее за его прямоту.

Ответ 9

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

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

Ответ 10

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

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

Ответ 11

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

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

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

df = df[cols]

Ответ 12

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

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)

Ответ 13

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

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

Ответ 14

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

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]

Ответ 15

Этот вопрос был дан ответ, прежде чем, но reindex_axis осуждается в настоящее время, так что я бы предложил использовать:

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

Ответ 16

set():

Простой подход использует set(), особенно если у вас длинный список столбцов и вы не хотите обрабатывать их вручную:

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

Ответ 17

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

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

Ответ 18

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

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

Ответ 19

Я попробовал функцию insert(), предложенную Уэсом МакКинни.

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

Это привело к тому, что Тимми хотел в одной строке без необходимости переместить последний столбец.

Ответ 20

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

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

Ответ 21

Вы можете использовать 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

Ответ 22

Вот как это сделать для любого количества столбцов.

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

Ответ 23

Я считаю, @Ответ Амана является лучшим, если вы знаете расположение другого столбца.

Если вы не знаете местоположение mean, но имеете только свое имя, вы не можете прибегать непосредственно к cols = cols[-1:] + cols[:-1]. Следующее - лучшее, что я мог придумать:

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

Ответ 25

Мне понравился ответ Shoresh, чтобы использовать установленные функции для удаления столбцов, когда вы не знаете местоположение, однако это не помогло мне в качестве цели, поскольку мне нужно сохранить исходный порядок столбцов (который имеет произвольные метки столбцов).

Я получил это, чтобы работать, используя IndexedSet из пакета boltons.

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

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

Надеюсь, это полезно любому, кто ищет эту тему для общего решения.

Ответ 26

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

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

Ответ 27

или может insert:

cols = [col for col in df if col != 'mean']
cols.insert(0,'mean')
df = df[cols]