python - seleccionar - ¿Cómo cambiar el orden de las columnas de DataFrame?
seleccionar columnas en pandas (25)
Desde agosto de 2018:
Si los nombres de sus columnas son demasiado largos para escribir, puede especificar el nuevo orden a través de una lista de enteros con las posiciones:
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
Y para el caso específico de la pregunta de OP:
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
Tengo el siguiente DataFrame
( df
):
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
Añado más columnas por asignación:
df[''mean''] = df.mean(1)
¿Cómo puedo mover la mean
la columna al frente, es decir, establecerla como primera columna sin tocar el orden de las otras columnas?
¿Qué hay de usar "T"?
df.T.reindex([''mean'',0,1,2,3,4]).T
@clocker: Su solución fue muy útil para mí, ya que quería traer dos columnas al frente desde un marco de datos en el que no sé exactamente los nombres de todas las columnas, porque se generaron a partir de una declaración dinámica antes. Por lo tanto, si se encuentra en la misma situación: para traer columnas al frente de las que sabe el nombre y luego dejar que sigan "todas las demás columnas", se me ocurrió la siguiente solución general;
df = df.reindex_axis([''Col1'',''Col2''] + list(df.columns.drop([''Col1'',''Col2''])), axis=1)
Aquí hay una función para hacer esto para cualquier número de columnas.
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
Aquí hay una manera de mover una columna existente que modificará el marco de datos existente en su lugar.
my_column = df.pop(''column name'')
df.insert(3, my_column.name, my_column)
Creo que la respuesta de @Aman es la mejor si conoces la ubicación de la otra columna.
Si no conoce la ubicación de la mean
, pero solo tiene su nombre, no puede recurrir directamente a cols = cols[-1:] + cols[:-1]
. Lo siguiente es lo mejor que podría encontrar:
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
En tu caso,
df = df.reindex_axis([''mean'',0,1,2,3,4], axis=1)
Hará exactamente lo que quieras.
En mi caso (forma general):
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)
actualización enero 2018
Si quieres usar reindex
:
df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=([''opened''] + list([a for a in df.columns if a != ''opened'']) ))
Esta función evita tener que enumerar cada variable en su conjunto de datos solo para ordenar algunas de ellas.
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
Toma dos argumentos, el primero es el conjunto de datos, el segundo son las columnas en el conjunto de datos que desea traer al frente.
Así que en mi caso tengo un conjunto de datos llamado Frame con las variables A1, A2, B1, B2, Total y Fecha. Si quiero llevar a Total al frente, todo lo que tengo que hacer es:
frame = order(frame,[''Total''])
Si quiero llevar el Total y la Fecha al frente, entonces hago:
frame = order(frame,[''Total'',''Date''])
EDITAR:
Otra forma útil de usar esto es, si tiene una tabla desconocida y busca variables con un término en particular, como VAR1, VAR2, ... puede ejecutar algo como:
frame = order(frame,[v for v in frame.columns if "VAR" in v])
Esta pregunta ya ha sido respondida before pero reindex_axis está obsoleto ahora, por lo que sugeriría usar:
df.reindex(sorted(df.columns), axis=1)
La forma más sencilla sería cambiar el orden de los nombres de columna como este
df = df[[''mean'', Col1,Col2,Col3]]
Me encontré con una pregunta similar, y solo quería agregar lo que decidí. Me gustó el reindex_axis() method
para cambiar el orden de las columnas. Esto funcionó:
df = df.reindex_axis([''mean''] + list(df.columns[:-1]), axis=1)
Un método alternativo basado en el comentario de @Jorge:
df = df.reindex(columns=[''mean''] + list(df.columns[:-1]))
Aunque reindex_axis
parece ser un poco más rápido en los micro benchmarks que en reindex
, creo que prefiero este último por su franqueza.
Me gustó la respuesta de Shoresh de usar la funcionalidad de configuración para eliminar columnas cuando no conoce la ubicación, sin embargo, esto no funcionó para mi propósito, ya que necesito mantener el orden de la columna original (que tiene etiquetas de columna arbitrarias).
Sin embargo, conseguí que esto funcionara utilizando IndexedSet del paquete boltons.
También necesitaba volver a agregar etiquetas de varias columnas, así que para un caso más general usé el siguiente código:
from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set([''mean'', ''std'']))
cols[0:0] =[''mean'', ''std'']
df = df[cols]
Espero que esto sea útil para cualquiera que busque en este hilo una solución general.
Mover cualquier columna a cualquier posición:
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]
Necesita crear una nueva lista de sus columnas en el orden deseado, luego use df = df[cols]
para reorganizar las columnas en este nuevo orden.
cols = [''mean''] + [col for col in df if col != ''mean'']
df = df[cols]
También puede utilizar un enfoque más general. En este ejemplo, la última columna (indicada por -1) se inserta como la primera columna.
cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]
También puede usar este enfoque para reordenar las columnas en un orden deseado si están presentes en el 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]
Probé la función insert()
como lo sugirió Wes McKinney.
df.insert (0, ''mean'', df.mean (1))
Esto obtuvo el resultado que Timmie quería, en una línea, sin la necesidad de mover esa última columna.
Puedes hacer lo siguiente (tomar partes prestadas de la respuesta de Aman):
cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))
cols
>>>[''mean'', 0L, 1L, 2L, 3L, 4L]
df = df[cols]
Puedes usar reindex
que puede usarse para ambos ejes:
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
Qué tal si:
df.insert(0, ''mean'', df.mean(1))
http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion
Simplemente asigne los nombres de las columnas en el orden que desee:
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]]
Ahora, la columna ''media'' sale en el frente:
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
Simplemente escriba el nombre de la columna que desea cambiar y establezca el índice para la nueva ubicación.
def change_column_order(df, col_name, index):
cols = df.columns.tolist()
cols.remove(col_name)
cols.insert(index, col_name)
return df[cols]
Para tu caso, esto sería como:
df = change_column_order(df, ''mean'', 0)
Simplemente haz
df = df[[''mean''] + df.columns[:-1].tolist()]
También podrías hacer algo como esto:
df = df[[''mean'', ''0'', ''1'', ''2'', ''3'']]
Puede obtener la lista de columnas con:
cols = list(df.columns.values)
La salida producirá:
[''0'', ''1'', ''2'', ''3'', ''mean'']
... que luego es fácil de reorganizar manualmente antes de colocarlo en la primera función
Una forma fácil sería reasignar el marco de datos con una lista de las columnas, reorganizadas según sea necesario.
Esto es lo que tienes ahora:
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'']
Reorganizar cols
en la forma que desee. Así es como moví el último elemento a la primera posición:
In [12]: cols = cols[-1:] + cols[:-1]
In [13]: cols
Out[13]: [''mean'', 0L, 1L, 2L, 3L, 4L]
Luego reordena el marco de datos de esta manera:
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
DataFrame.sort_index(axis=1)
está bastante limpio. Revise el documento aquí . Y luego concat
set()
:
Un enfoque simple es usar set()
, en particular cuando tiene una larga lista de columnas y no quiere manejarlas manualmente:
cols = list(set(df.columns.tolist()) - set([''mean'']))
cols.insert(0, ''mean'')
df = df[cols]