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