Comment changer l'ordre des colonnes de DataFrame?
j'ai le suivant DataFrame
( df
):
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
ajouter plus de colonne (s) par affectation:
df['mean'] = df.mean(1)
Comment puis-je déplacer la colonne mean
à l'avant, c'est à dire définir comme première colonne de quitter l'ordre des autres colonnes intactes?
26 réponses
un moyen facile serait de réassigner le datagramme avec une liste des colonnes, réarrangées au besoin.
c'est Ce que vous avez maintenant:
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']
réarrangez cols
comme vous voulez. C'est ainsi que j'ai déplacé le dernier élément à la première position:
In [12]: cols = cols[-1:] + cols[:-1]
In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]
puis réordonner la base de données comme ceci:
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
vous pourriez aussi faire quelque chose comme ceci:
df = df[['mean', '0', '1', '2', '3']]
Vous pouvez obtenir la liste des colonnes avec:
cols = list(df.columns.values)
la sortie produira:
['0', '1', '2', '3', 'mean']
...qui est alors facile à réarranger manuellement avant de le laisser tomber dans la première fonction
il suffit d'assigner les noms de colonne dans l'ordre où vous les voulez:
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]]
maintenant, la colonne "moyenne" apparaît à l'avant:
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
Que Diriez-vous de:
df.insert(0, 'mean', df.mean(1))
http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion
dans votre cas,
df = df.reindex_axis(['mean',0,1,2,3,4], axis=1)
fera exactement ce que vous voulez.
dans mon cas (formulaire général):
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)
mise à jour Jan 2018
si vous voulez utiliser reindex
:
df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))
vous devez créer une nouvelle liste de vos colonnes dans l'ordre désiré, puis utiliser df = df[cols]
pour réorganiser les colonnes dans ce nouvel ordre.
cols = ['mean'] + [col for col in df if col != 'mean']
df = df[cols]
Vous pouvez également utiliser une approche plus générale. Dans cet exemple, la dernière colonne (indiquée par -1) est insérée comme première colonne.
cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]
vous pouvez également utiliser cette approche pour réordonner les colonnes dans un ordre désiré si elles sont présentes dans la base de données.
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]
tout Simplement,
df = df[['mean'] + df.columns[:-1].tolist()]
cette fonction vous évite d'avoir à énumérer toutes les variables de votre ensemble de données pour en commander quelques-unes.
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
il faut deux arguments, le premier est l'ensemble de données, le second sont les colonnes dans l'ensemble de données que vous voulez apporter à l'avant.
donc dans mon cas j'ai un ensemble de données appelé Frame avec les variables A1, A2, B1, B2, Total et Date. Si je veux amener Total à l'avant alors tout ce que j'ai à faire est:
frame = order(frame,['Total'])
si je veux apporter Total et Date à l'avant alors je fais:
frame = order(frame,['Total','Date'])
EDIT:
une autre façon utile d'utiliser ceci est, si vous avez une table inconnue et que vous cherchez des variables avec un terme particulier, comme VAR1, VAR2,... vous pouvez exécuter quelque chose comme:
frame = order(frame,[v for v in frame.columns if "VAR" in v])
j'ai moi-même rencontré une question similaire, et je voulais juste ajouter ce que j'ai décidé. J'ai aimé le reindex_axis() method
pour changer l'ordre des colonnes. Cela a fonctionné:
df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)
une autre méthode basée sur le commentaire de @Jorge:
df = df.reindex(columns=['mean'] + list(df.columns[:-1]))
bien que reindex_axis
semble être légèrement plus rapide dans les micro benchmarks que reindex
, je pense que je préfère ce dernier pour sa franchise.
vous pourriez faire ce qui suit (en empruntant des parties de la réponse D'Aman):
cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))
cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]
df = df[cols]
tapez juste le nom de la colonne que vous voulez changer, et mettez l'index pour le nouvel emplacement.
def change_column_order(df, col_name, index):
cols = df.columns.tolist()
cols.remove(col_name)
cols.insert(index, col_name)
return df[cols]
Pour votre cas, ce serait comme:
df = change_column_order(df, 'mean', 0)
À Partir D'Août 2018:
une approche plus souple si vous n'avez pas trop de colonnes et de noms de colonnes non-entiers (qui sont trop longs à taper explicitement), serait de spécifier l'ordre complet à travers une liste:
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
et pour le cas particulier de la question de L'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
la façon La plus simple serait de changer l'ordre des noms de colonnes comme ceci
df = df[['mean', Col1,Col2,Col3]]
déplacement de n'importe quelle colonne à n'importe quelle position:
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]
j'ai essayé la fonction insert()
comme suggéré par Wes McKinney.
df.insérer (0, "moyenne", df.moyenne (1))"
cela a obtenu le résultat que Timmie voulait, dans une ligne, sans la nécessité de déplacer cette dernière colonne.
set()
:
une approche simple est d'utiliser set()
, en particulier lorsque vous avez une longue liste de colonnes et que vous ne voulez pas les manipuler manuellement:
cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
Voici une façon de déplacer une colonne existante qui modifiera la base de données existante en place.
my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)
@clocker: votre solution a été très utile pour moi, car je voulais apporter deux colonnes à l'avant d'un datagramme où je ne sais pas exactement les noms de toutes les colonnes, parce qu'elles sont générées à partir d'une instruction de pivot avant. Donc, si vous êtes dans la même situation: pour faire apparaître des colonnes dont vous connaissez le nom et les laisser suivre par "toutes les autres colonnes", j'ai trouvé la solution générale suivante:
df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
Vous pouvez utiliser reindex
qui peut être utilisé pour les deux axes:
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
Voici une fonction pour faire ceci pour n'importe quel nombre de colonnes.
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
je crois @Aman réponse est le meilleur si vous connaissez l'emplacement de l'autre colonne.
Si vous ne connaissez pas l'emplacement de mean
, mais seulement son nom, vous ne pouvez pas recourir directement à cols = cols[-1:] + cols[:-1]
. Voici ce que j'ai trouvé de mieux:
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
DataFrame.sort_index(axis=1)
est assez propre. Check doc ici .
Et puis concat
j'ai aimé Shoresh la réponse de pour utiliser l'ensemble des fonctionnalités de supprimer des colonnes lorsque vous ne connaissez pas l'emplacement, cependant cela n'a pas fonctionné pour mon objectif que j'ai besoin de garder la colonne d'origine (ce qui est arbitraire des étiquettes de colonne).
j'ai obtenu cela pour travailler cependant en utilisant ensemble indexé du paquet boltons.
j'ai aussi besoin de rajouter plusieurs étiquettes de colonne, donc pour un cas plus général que j'ai utilisé le code suivant:
from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set(['mean', 'std']))
cols[0:0] =['mean', 'std']
df = df[cols]
espère que ceci est utile à quiconque recherche ce fil pour une solution générale.
ou peut faire insert
:
cols = [col for col in df if col != 'mean']
cols.insert(0,'mean')
df = df[cols]