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

avatar
Timmie
30 октября 2012 в 22:22
1545927
42
1215

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

import numpy as np
import pandas as pd

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

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

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

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

Источник
jpp
3 октября 2018 в 08:31
1

Для обобщенного решения на основе NumPy см. Как переместить столбец в кадре данных pandas, предполагает только один уровень столбца, то есть нет MultiIndex.

ravibeli
6 июня 2020 в 13:49
0

Достаточно поискав, я получил эту лучшую ссылку для столбцов, переупорядочивающих несколько логик довольно простыми терминами [столбцы переупорядочивают логику для панд] [datasciencemadesimple.com/…

Ответы (42)

avatar
my0wn0pini0n
8 декабря 2021 в 14:05
1

Сортировка не гарантирует сохранения правильного порядка. Объединив ['mean'] со списком столбцов, он будет равен

.
cols_list = ['mean'] + df.columns.tolist()
df['mean'] = df.mean(1)
df = df[cols_list]
avatar
Chadee Fouad
6 ноября 2021 в 04:42
1

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

df = df['FILE_NAME DISPLAY_PATH SHAREPOINT_PATH RETAILER LAST_UPDATE'.split()]
avatar
Giorgos Myrianthous
15 августа 2021 в 22:41
0

Другим вариантом может быть использование метода set_index() с последующим reset_index(). Обратите внимание, что сначала мы pop() столбец, который мы собираемся переместить в начало кадра данных, чтобы избежать конфликта имен при сбросе индекса:

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

Подробнее см. Как изменить порядок столбцов фрейма данных в pandas.

avatar
sanzo213
21 июля 2021 в 05:07
-1

Я попытался создать функцию порядка, с помощью которой можно переупорядочивать/перемещать столбцы со ссылкой на команду порядка Stata. было бы лучше создать py-файл (имя которого может быть order.py), сохранить его в каталоге и назвать его function

def order(dataframe,cols,f_or_l=None,before=None, after=None):

#만든이: 김완석, Stata로 뚝딱뚝딱 저자, blog.naver.com/sanzo213 운영
# 갖다 쓰시거나 수정을 하셔도 되지만 출처는 꼭 밝혀주세요
# cols옵션 및 befor/after옵션에 튜플이 가능하게끔 수정했으며, 오류문구 수정함(2021.07.12,1)
# 칼럼이 멀티인덱스인 상태에서 reset_index()메소드 사용했을 시 적용안되는 걸 수정함(2021.07.12,2) 

import pandas as pd
if (type(cols)==str) or (type(cols)==int) or (type(cols)==float) or (type(cols)==bool) or type(cols)==tuple:    
    cols=[cols]
    
dd=list(dataframe.columns)
for i in cols:
    i
    dd.remove(i) #cols요소를 제거함
    
if (f_or_l==None) & ((before==None) & (after==None)):
    print('f_or_l옵션을 쓰시거나 아니면 before옵션/after옵션 쓰셔야되요')
    
if ((f_or_l=='first') or (f_or_l=='last')) & ~((before==None) & (after==None)):
    print('f_or_l옵션 사용시 before after 옵션 사용불가입니다.')
    
if (f_or_l=='first') & (before==None) & (after==None):
    new_order=cols+dd
    dataframe=dataframe[new_order]
    return dataframe

if (f_or_l=='last') & (before==None) & (after==None):   
    new_order=dd+cols
    dataframe=dataframe[new_order]
    return dataframe
    
if (before!=None) & (after!=None):
    print('before옵션 after옵션 둘다 쓸 수 없습니다.')
    

if (before!=None) & (after==None) & (f_or_l==None):

    if not((type(before)==str) or (type(before)==int) or (type(before)==float) or
       (type(before)==bool) or ((type(before)!=list)) or 
       ((type(before)==tuple))):
        print('before옵션은 칼럼 하나만 입력가능하며 리스트 형태로도 입력하지 마세요.')
    
    else:
        b=dd[:dd.index(before)]
        a=dd[dd.index(before):]
        
        new_order=b+cols+a
        dataframe=dataframe[new_order]  
        return dataframe
    
if (after!=None) & (before==None) & (f_or_l==None):

    if not((type(after)==str) or (type(after)==int) or (type(after)==float) or
       (type(after)==bool) or ((type(after)!=list)) or 
       ((type(after)==tuple))):
            
        print('after옵션은 칼럼 하나만 입력가능하며 리스트 형태로도 입력하지 마세요.')  

    else:
        b=dd[:dd.index(after)+1]
        a=dd[dd.index(after)+1:]
        
        new_order=b+cols+a
        dataframe=dataframe[new_order]
        return dataframe

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

# module

import pandas as pd
import numpy as np
from order import order # call order function from order.py file

# make a dataset

columns='a b c d e f g h i j k'.split()
dic={}

n=-1
for i in columns:
    
    n+=1
    dic[i]=list(range(1+n,10+1+n))
data=pd.DataFrame(dic)
print(data)

# use order function (1) : order column e in the first

data2=order(data,'e',f_or_l='first')
print(data2)

# use order function (2): order column e in the last , "data" dataframe

print(order(data,'e',f_or_l='last'))


# use order function (3) : order column i before column c in "data" dataframe

print(order(data,'i',before='c'))


# use order function (4) : order column g after column b in "data" dataframe

print(order(data,'g',after='b'))

# use order function (4) : order columns ['c', 'd', 'e'] after column i in "data" dataframe

print(order(data,['c', 'd', 'e'],after='i'))
avatar
S.Baum
5 мая 2021 в 09:49
0

Я подумал о том же, что и Дмитрий Ворк, явно самый простой ответ:

df["mean"] = df.mean(1)
l =  list(np.arange(0,len(df.columns) -1 ))
l.insert(0,-1)
df.iloc[:,l]
avatar
Sam Murphy
13 апреля 2021 в 13:36
14

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

df = df.filter(list_of_col_names)

avatar
abc
26 марта 2021 в 14:10
1

Как и в предыдущем ответе, существует альтернатива с использованием deque() и ее метода rotate(). Метод rotate берет последний элемент в списке и вставляет его в начало:

.
from collections import deque

columns = deque(df.columns.tolist())
columns.rotate()

df = df[columns]
avatar
Xopi García
10 декабря 2020 в 16:32
0

Чтобы установить существующий столбец справа/слева от другого на основе их имен:

def df_move_column(df, col_to_move, col_left_of_destiny="", right_of_col_bool=True):
    cols = list(df.columns.values)
    index_max = len(cols) - 1

    if not right_of_col_bool:
        # set left of a column "c", is like putting right of column previous to "c"
        # ... except if left of 1st column, then recursive call to set rest right to it
        aux = cols.index(col_left_of_destiny)
        if not aux:
            for g in [x for x in cols[::-1] if x != col_to_move]:
                df = df_move_column(
                        df, 
                        col_to_move=g, 
                        col_left_of_destiny=col_to_move
                        )
            return df
        col_left_of_destiny = cols[aux - 1]

    index_old = cols.index(col_to_move)
    index_new = 0
    if len(col_left_of_destiny):
        index_new = cols.index(col_left_of_destiny) + 1

    if index_old == index_new:
        return df

    if index_new < index_old:
        index_new = np.min([index_new, index_max])
        cols = (
            cols[:index_new]
            + [cols[index_old]]
            + cols[index_new:index_old]
            + cols[index_old + 1 :]
        )
    else:
        cols = (
            cols[:index_old]
            + cols[index_old + 1 : index_new]
            + [cols[index_old]]
            + cols[index_new:]
        )

    df = df[cols]
    return df

Например,

cols = list("ABCD")
df2 = pd.DataFrame(np.arange(4)[np.newaxis, :], columns=cols)
for k in cols:
    print(30 * "-")
    for g in [x for x in cols if x != k]:
        df_new = df_move_column(df2, k, g)
        print(f"{k} after {g}:  {df_new.columns.values}")
for k in cols:
    print(30 * "-")
    for g in [x for x in cols if x != k]:
        df_new = df_move_column(df2, k, g, right_of_col_bool=False)
        print(f"{k} before {g}:  {df_new.columns.values}")

Вывод:

enter image description here

avatar
Mathia Haure-Touzé
4 июля 2020 в 10:19
6

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

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
avatar
rra
18 июня 2020 в 19:30
6

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

Вы можете сделать это после добавления столбца «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

avatar
liangli
30 мая 2020 в 05:12
61

Предположим, у вас есть df со столбцами A B C.

Самый простой способ:

df = df.reindex(['B','C','A'], axis=1)
cheevahagadog
23 сентября 2020 в 15:29
0

Одна замечательная особенность этой опции заключается в том, что вы можете использовать ее в операциях pandas pipe!

Andreas Forslöw
8 декабря 2020 в 09:13
1

Обратите внимание, что это вернет только переиндексированный фрейм данных - не изменит используемый экземпляр df. Если вы хотите использовать переиндексированный df, просто используйте возвращаемое значение: df2 = df.reindex(['B', 'C', 'A'], axis=1). Спасибо за этот ответ!

liangli
25 февраля 2021 в 03:04
0

@cheevahagadog Хороший момент!

liangli
25 февраля 2021 в 03:05
0

@ AndreasForslöw Спасибо, что подчеркнули это.

avatar
CSQL
8 мая 2020 в 15:42
4

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

df = df[df.columns.reindex(['mean', 0, 1, 2, 3, 4])[0]]
avatar
plhn
10 апреля 2020 в 11:39
5

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

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

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

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]
avatar
hayj
26 марта 2020 в 16:32
1

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

def reorder_df_columns(df, start=None, end=None):
    """
        This function reorder columns of a DataFrame.
        It takes columns given in the list `start` and move them to the left.
        Its also takes columns in `end` and move them to the right.
    """
    if start is None:
        start = []
    if end is None:
        end = []
    assert isinstance(start, list) and isinstance(end, list)
    cols = list(df.columns)
    for c in start:
        if c not in cols:
            start.remove(c)
    for c in end:
        if c not in cols or c in start:
            end.remove(c)
    for c in start + end:
        cols.remove(c)
    cols = start + cols + end
    return df[cols]
avatar
user_stack_overflow
11 декабря 2019 в 23:42
1

У меня есть очень специфический вариант использования для изменения порядка имен столбцов в pandas. Иногда я создаю новый столбец в кадре данных, основанный на существующем столбце. По умолчанию панды вставят мой новый столбец в конец, но я хочу, чтобы новый столбец был вставлен рядом с существующим столбцом, из которого он получен.

enter image description here

def rearrange_list(input_list, input_item_to_move, input_item_insert_here):
    '''
    Helper function to re-arrange the order of items in a list.
    Useful for moving column in pandas dataframe.

    Inputs:
        input_list - list
        input_item_to_move - item in list to move
        input_item_insert_here - item in list, insert before 

    returns:
        output_list
    '''
    # make copy for output, make sure it's a list
    output_list = list(input_list)

    # index of item to move
    idx_move = output_list.index(input_item_to_move)

    # pop off the item to move
    itm_move = output_list.pop(idx_move)

    # index of item to insert here
    idx_insert = output_list.index(input_item_insert_here)

    # insert item to move into here
    output_list.insert(idx_insert, itm_move)

    return output_list


import pandas as pd

# step 1: create sample dataframe
df = pd.DataFrame({
    'motorcycle': ['motorcycle1', 'motorcycle2', 'motorcycle3'],
    'initial_odometer': [101, 500, 322],
    'final_odometer': [201, 515, 463],
    'other_col_1': ['blah', 'blah', 'blah'],
    'other_col_2': ['blah', 'blah', 'blah']
})
print('Step 1: create sample dataframe')
display(df)
print()

# step 2: add new column that is difference between final and initial
df['change_odometer'] = df['final_odometer']-df['initial_odometer']
print('Step 2: add new column')
display(df)
print()

# step 3: rearrange columns
ls_cols = df.columns
ls_cols = rearrange_list(ls_cols, 'change_odometer', 'final_odometer')
df=df[ls_cols]
print('Step 3: rearrange columns')
display(df)
avatar
Pygirl
9 ноября 2019 в 06:24
86
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 мкс

ratnesh
1 апреля 2020 в 13:15
2

решение 1 - это то, что мне нужно, так как у меня слишком много столбцов (53), спасибо

sergzemsk
10 апреля 2020 в 21:46
2

@Pygirl, какое значение показывает реальное затраченное время? (пользователь, система, общее или настенное время)

Gustavo Rottgering
15 мая 2020 в 00:36
2

Для меня это лучший ответ на проблему. Так много решений (в том числе и то, что мне было нужно) и простой подход. Спасибо!

Dmitriy Work
20 мая 2020 в 16:55
2

Решение 6 (без понимания списка): df = df.iloc[:, [1, 2, 3, 0]]

Pygirl
29 сентября 2020 в 04:58
2

@sergzemsk: coderhelper.com/a/55702033/6660373. Сравниваю по времени на стене.

Asclepius
15 января 2021 в 15:34
2

Решение 3 - единственный хороший подход из перечисленных, потому что это единственный действующий подход, который не влияет на индекс. Те, которых нет на месте, не масштабируются.

avatar
erncyp
5 ноября 2019 в 16:33
24

Я думаю, что это более подходящее решение:

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

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

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

Roko Mijic
12 июня 2020 в 12:11
0

это хорошо, но что, если вы хотите, чтобы все было в конце?

erncyp
12 июня 2020 в 15:55
1

Любой новый столбец, который вы создаете, добавляется в конец, поэтому я предполагаю, что это будет df["mean"] = df.pop("mean")

avatar
Kweweli
25 октября 2019 в 20:08
2

Большинство ответов не были достаточно обобщены, и метод pandas reindex_axis немного утомителен, поэтому я предлагаю простую функцию для перемещения произвольного количества столбцов в любую позицию с использованием словаря, где ключ = имя столбца и значение = позиция для перемещения к. Если ваш фрейм данных большой, передайте True в «big_data», тогда функция вернет список упорядоченных столбцов. И вы можете использовать этот список для разделения данных.

def order_column(df, columns, big_data = False):

    """Re-Orders dataFrame column(s)
       Parameters : 
       df      -- dataframe
       columns -- a dictionary:
                  key   = current column position/index or column name
                  value = position to move it to  
       big_data -- boolean 
                  True = returns only the ordered columns as a list
                          the user user can then slice the data using this
                          ordered column
                  False = default - return a copy of the dataframe
    """
    ordered_col = df.columns.tolist()

    for key, value in columns.items():

        ordered_col.remove(key)
        ordered_col.insert(value, key)

    if big_data:

        return ordered_col

    return df[ordered_col]

# e.g.
df = pd.DataFrame({'chicken wings': np.random.rand(10, 1).flatten(), 'taco': np.random.rand(10,1).flatten(),
                          'coffee': np.random.rand(10, 1).flatten()})
df['mean'] = df.mean(1)

df = order_column(df, {'mean': 0, 'coffee':1 })

>>>

output

col = order_column(df, {'mean': 0, 'coffee':1 }, True)

col
>>>
['mean', 'coffee', 'chicken wings', 'taco']

# you could grab it by doing this

df = df[col]

avatar
Kaustubh J
11 апреля 2019 в 17:58
4

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

df.insert(0, "test", df["mean"])
df = df.drop(columns=["mean"]).rename(columns={"test": "mean"})
avatar
Yuca
20 августа 2018 в 17:35
55

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

Данные:

          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 относится к фактическим позициям, а не к именам столбцов.

Для конкретного случая вопроса OP:

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

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

avatar
pomber
27 февраля 2018 в 14:05
10

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

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]
avatar
freeB
29 января 2018 в 18:57
2

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

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
avatar
Joe Heffer
4 января 2018 в 13:25
11

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

my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)  # Is in-place
Asclepius
15 января 2021 в 15:41
0

Это практически единственный хороший подход, поскольку он на месте. Большинство других подходов не применяются и поэтому не масштабируются.

avatar
silgon
18 декабря 2017 в 15:24
4

Вы можете использовать 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
avatar
Jamelade
9 декабря 2017 в 04:14
2

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

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

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

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

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

Shoresh
2 октября 2019 в 22:09
0

Я немного удивлен! Я довольно часто использую set для этой цели и никогда не имел дела с заказами.

avatar
Shoresh
12 сентября 2017 в 02:06
3

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

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
pnv
6 марта 2018 в 05:31
2

Одно предостережение: порядок столбцов изменится, если вы поместите его в набор

Shoresh
6 марта 2018 в 14:50
0

Интересно! @ user1930402 Я пробовал описанный выше подход несколько раз и никогда не испытывал никаких проблем. Я еще раз перепроверю.

avatar
Shihe Zhang
23 августа 2017 в 12:12
0

DataFrame.sort_index(axis=1) довольно чистый.Проверьте документ здесь. А затем concat

Mitali Cyrus
21 февраля 2020 в 05:12
0

Хотя функция sort_index чистая, мне жаль это говорить, но я не думаю, что она решает вопрос, который больше касается переупорядочения столбцов (которые могут следовать или не следовать какому-то определенному порядку), чем их сортировка.

avatar
matthhias
27 июля 2017 в 09:21
7

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

df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
avatar
otteheng
8 декабря 2016 в 15:22
12

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

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

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

df = df[cols]
avatar
Alvaro Joao
30 августа 2016 в 21:57
167

В вашем случае

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']) ))
Konstantin
27 ноября 2017 в 09:10
2

Я пытался установить copy=False, но похоже, что reindex_axis все еще создает копию.

Alvaro Joao
27 ноября 2017 в 14:11
1

@Konstantin, вы можете задать еще один вопрос по этой проблеме? Было бы лучше иметь больше контекста

avatar
ZEE
26 июня 2016 в 23:46
3

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

df = df.T.reindex(['mean', 0, 1, 2, 3, 4]).T
avatar
ccerhan
6 мая 2016 в 11:39
10

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

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)
avatar
Alexander
21 августа 2015 в 02:18
81

Вам необходимо создать новый список ваших столбцов в желаемом порядке, а затем использовать 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]
avatar
fixxxer
28 апреля 2015 в 14:19
365

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

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
user3226167
2 июня 2017 в 02:02
10

Делает копию?

AGS
21 июля 2017 в 20:19
36

@NicholasMorley - это не лучший ответ, если у вас, скажем, 1000 столбцов в вашем df.

3pitt
19 февраля 2018 в 19:09
1

не похоже, что вы назначаете <df>.columns, как вы утверждаете изначально

Dongkyu Choi
19 апреля 2018 в 23:12
10

Это лучший ответ для небольшого количества столбцов.

James Hirschorn
4 мая 2018 в 21:40
6

Это просто копия более раннего ответа @freddygv. Это должен быть принятый ответ, а не это.

avatar
Napitupulu Jon
28 апреля 2015 в 09:50
17

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

df = df[['mean'] + df.columns[:-1].tolist()]
parvij
5 января 2016 в 11:10
0

TypeError: невозможно неявно преобразовать объект int в str

Napitupulu Jon
8 января 2016 в 10:28
0

возможно, API изменился, вы также можете это сделать ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order

hlongmore
20 июня 2017 в 19:41
1

Вариант этого хорошо сработал для меня. Имея существующий список headers, который использовался для создания словаря, который затем использовался для создания DataFrame, я вызвал df.reindex(columns=headers). Единственная проблема, с которой я столкнулся, заключалась в том, что я уже вызвал df.set_index('some header name', inplace=True), поэтому, когда переиндексирование было выполнено, он добавил еще один столбец с именем some header name, поскольку исходный столбец теперь был индексом. Что касается синтаксиса, указанного выше, ['mean'] + df.columns в интерпретаторе python дает мне Index(u'meanAddress', u'meanCity', u'meanFirst Name'...

Napitupulu Jon
21 июня 2017 в 00:56
1

@hlongmore: я не знаю, что у вас есть предыдущий код, но редактирование должно работать (с использованием 0.19.2)

hlongmore
22 июня 2017 в 17:49
0

Редактирование действительно работает (у меня 0.20.2). В моем случае у меня уже есть нужные столбцы, поэтому я думаю, что df.reindex () - это то, что мне действительно следует использовать.

Moot
12 июля 2017 в 06:21
0

Этот ответ кажется неправильным: он не перемещает средний столбец так, чтобы он стал первым столбцом. Скорее, он переименовывает первый столбец в «означает» и переименовывает последний столбец в 4. Я был почти обманут, сделав что-то очень неправильно, но, к счастью, сначала проверил это сам. Я бы посоветовал вместо этого сделать что-то вроде: «df = df [list (reversed (df.columns))]» или посмотреть другие варианты ответов на этот вопрос.

Napitupulu Jon
12 июля 2017 в 08:27
0

Ой, как я мог это пропустить? Однако до того, как я редактировал ранее, он все еще работает. Я отредактировал свой ответ.

avatar
FooBar
22 марта 2015 в 14:43
2

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

Если вы не знаете местоположение 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
avatar
clocker
27 августа 2014 в 19:49
21

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

Jorge
8 августа 2018 в 21:32
7

Это было хорошее решение, но reindex_axis будет устаревшим. Я использовал переиндекс, и он работал нормально.

mins
15 декабря 2020 в 10:30
0

Я могу что-то пропустить, но 1 / вы, вероятно, забыли включить axis=1 во второе решение, чтобы использовать столбцы, а не строки. 2 / В 2020 году решение reindex изменяет порядок строк / столбцов, но также очищает данные (NaN везде).

avatar
seeiespi
29 июля 2014 в 19:30
18

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

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

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

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

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

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

frame = order(frame,[v for v in frame.columns if "VAR" in v])
avatar
freddygv
19 мая 2014 в 15:20
648

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

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

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

cols = list(df.columns.values)

Результатом будет:

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

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

Jim
9 октября 2015 в 22:14
9

Вы также можете получить список столбцов со списком (df.columns)

Jim
9 октября 2015 в 22:22
19

или df.columns.tolist()

Sid
20 марта 2018 в 15:18
0

Для новичков вроде меня измените список, полученный от холода. Тогда df = df [columns] i.s. упорядоченный список помещается в первое выражение без единой скобки.

prosti
5 мая 2019 в 01:10
0

Имена столбцов будут целыми числами в 3.x df = df[['mean1', 0, 1, 2, 3]]

Robvh
25 июля 2019 в 08:22
4

Я не думаю, что это хороший ответ, поскольку он не предоставляет кода, как изменить порядок столбцов любого фрейма данных. Скажем, я импортирую файл csv как pandas pd как pd.read_csv(). Как ваш ответ может быть использован для изменения порядка столбцов?

daniel brandstetter
9 сентября 2019 в 23:27
2

@Robvh, вторая строка кода объясняет, как получить существующие имена столбцов. Оттуда вы можете скопировать вывод в первую строку кода и перестроить по желанию. Единственная другая информация, которую следует знать, - это то, что без заголовка имена столбцов по умолчанию являются целыми числами, а не строками.

Uralan
9 июля 2020 в 12:01
0

Я согласен. Это простое и понятное решение проблемы. Хотя, если вы имеете дело с большим количеством столбцов, это не идеально. Выручил меня хотя

avatar
dmvianna
4 января 2013 в 06:04
40

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

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

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

df = df.reindex(['the','order','you','want'], axis=1)

Теперь, как вы хотите отсортировать список имен столбцов, на самом деле не вопрос pandas, это вопрос манипулирования списком Python. Есть много способов сделать это, и я думаю, что в этом ответе есть очень изящный способ сделать это.

smci
17 апреля 2013 в 13:06
21

Нет, это другое. Там пользователь хочет отсортировать все столбцы по имени. Здесь они хотят переместить один столбец в первый, оставив порядок остальных столбцов нетронутым.

Chankey Pathak
8 июня 2017 в 10:16
2

Что делать, если вы не хотите их сортировать?

mins
15 декабря 2020 в 09:51
0

Ответ не решает проблему в вопросе.

dmvianna
16 декабря 2020 в 00:14
1

@mins Я надеюсь, что приведенное выше изменение достаточно ясно. :)

mins
16 декабря 2020 в 10:30
0

Теперь ваша редакция показывает рабочее решение проблемы. Спасибо.

avatar
Wes McKinney
9 ноября 2012 в 21:04
195
jason
27 мая 2014 в 01:23
56

Может ли эта функция быть добавлена ​​к pandas в будущем? что-то вроде df.move(0,df.mean)?

Imad
12 июня 2018 в 09:10
0

Ой, это даже работает так: df_metadata.insert(0,'Db_name',"raw_data") (Код не имеет отношения к этой теме)

cucu8
2 августа 2018 в 10:29
5

Красивый. И это тоже происходит на месте.

CKM
19 августа 2019 в 17:00
3

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

spinup
24 февраля 2020 в 21:07
10

Это работает для вопроса OP при создании нового столбца, но не для перемещения столбца; попытка переместить результаты в *** ValueError: cannot insert mean, already exists

Sumanth Lazarus
29 июля 2020 в 05:22
6

Это чистое решение. Современный метод API: df.insert(0, 'mean', df['mean'])

mins
15 декабря 2020 в 09:31
1

Новая ссылка на документацию: pandas.pydata.org/pandas-docs/stable/user_guide/…

Victor Di
31 марта 2021 в 10:58
1

@spinup, если у вас уже есть столбец, вы можете вставить его под другим временным именем, удалить исходный столбец и затем вернуть временное имя исходному: df.insert(0, 'mean_temp', df['mean']) df.drop('mean', axis=1, inplace=True) df.rename(columns={'mean_temp': 'mean'}, inplace=True)

avatar
Aman
30 октября 2012 в 22:38
1108

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

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

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
moeabdol
9 января 2015 в 16:59
25

если вы получили сообщение «не удается объединить объекты 'str' и 'list'», убедитесь, что вы [] значение str в столбцах: cols = [cols [7]] + cols [: 7] + cols [8:]

Snorfalorpagus
5 ноября 2015 в 12:59
1

Есть ли причина использовать df.ix[:, cols] вместо df[cols]?

FooBar
6 октября 2016 в 15:54
1

FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union() '''. Я предлагаю заменить строку cols на cols[-1:].union(cols[:-1]), что дает тот же результат.

Aman
6 октября 2016 в 22:08
3

@FooBar Это не объединение множеств, это конкатенация двух упорядоченных списков.

FooBar
7 октября 2016 в 06:13
3

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

alexis
28 февраля 2017 в 15:19
2

@FooBar, тип cols - list; он даже позволяет дублировать (которые будут отброшены при использовании во фрейме данных). Вы думаете о Index объектах.

Konstantin
27 ноября 2017 в 08:48
13

Это подразумевает копирование ВСЕХ данных, что крайне неэффективно. Мне хотелось, чтобы у панд был способ сделать это, не создавая копии.

Christina
15 сентября 2021 в 13:18
0

Лучший ответ, который наконец помог мне