2012-06-16 13 views
134

Ho un dataframe con oltre 200 colonne (non chiedere perché). Il problema è come sono stati generati l'ordine èPanda Python - Riordino delle colonne in un dataframe in base al nome della colonna

['Q1.3','Q6.1','Q1.2','Q1.1',......] 

ho bisogno di riordinare le colonne come segue:

['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 

C'è qualche modo per me di fare questo all'interno di pitone?

+16

Perché hai 200 colonne? ;) –

+0

Possibile duplicato di [Come modificare l'ordine delle colonne DataFrame?] (Https://stackoverflow.com/questions/13148429/how-to-change-the-order-of-dataframe-columns) –

risposta

171
df.reindex_axis(sorted(df.columns), axis=1) 

Questo presuppone che l'ordinamento dei nomi delle colonne darà l'ordine desiderato. Se i nomi delle colonne non vengono ordinati lessicograficamente (ad es., Se vuoi che la colonna Q10.3 appaia dopo la Q9.1), dovrai ordinare in modo diverso, ma ciò non ha nulla a che fare con i panda.

+2

Mi piace questo perché lo stesso metodo può essere usato per ordinare le righe (avevo bisogno di ordinare righe e colonne). Mentre è lo stesso metodo, puoi omettere l'argomento 'axis' (o fornire il suo valore predefinito,' 0'), come 'df.reindex_axis (sort (non_sorted_row_index))' che è equivalente a 'df.reindex (ordinato (non_sorted_row_index)) ' –

+0

Nota che la reindicizzazione non viene eseguita sul posto, quindi per applicare effettivamente l'ordinamento al df devi usare' df = df.reindex_axis (...) '. Inoltre, si noti che gli ordinamenti non-lessicografici sono facili con questo approccio, poiché l'elenco dei nomi delle colonne può essere ordinato separatamente in un ordine arbitrario e quindi passato a 'reindex_axis'. Questo non è possibile con l'approccio alternativo proposto da @Wes McKinney ('df = df.sort_index (axis = 1)'), che è tuttavia più pulito per i tipi puri lessicografici. – WhoIsJack

0

Il sort metodo e sorted funzione consentono di fornire una funzione personalizzata per estrarre la chiave utilizzata per il confronto:

>>> ls = ['Q1.3', 'Q6.1', 'Q1.2'] 
>>> sorted(ls, key=lambda x: float(x[1:])) 
['Q1.2', 'Q1.3', 'Q6.1'] 
+0

Questo funziona per gli elenchi in generale e ho familiarità con esso. Come si applica a un DataFrame panda? – pythOnometrist

+1

Non sono sicuro, ammetto che la mia risposta non era specifica per questa libreria. – tweet

186

Si può anche fare di più succintamente:

df.sort_index(axis=1)

Edit:

Assicurati di tenere il valore

df = df.sort_index(axis=1)

o di farlo in luogo

df.sort_index(axis=1, inplace=True)

+2

ricorda di fare 'df = df.sort_index (axis = 1)', per @multigoodverse – GoJian

+5

o modifica 'df' sul posto con' df.sort_index (axis = 1, inplace = True) ' – Jakub

+1

Questo dovrebbe essere # 1 –

16

Tweet's answer può essere passato alla risposta di BrenBarn sopra con

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

Così, per il tuo esempio, dire:

vals = randint(low=16, high=80, size=25).reshape(5,5) 
cols = ['Q1.3', 'Q6.1', 'Q1.2', 'Q9.1', 'Q10.2'] 
data = DataFrame(vals, columns = cols) 

Si ottiene:

data 

    Q1.3 Q6.1 Q1.2 Q9.1 Q10.2 
0 73  29  63  51  72 
1 61  29  32  68  57 
2 36  49  76  18  37 
3 63  61  51  30  31 
4 36  66  71  24  77 

Poi fare:

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

conseguente:

data 


    Q1.2 Q1.3 Q6.1 Q9.1 Q10.2 
0 2  0  1  3  4 
1 7  5  6  8  9 
2 2  0  1  3  4 
3 2  0  1  3  4 
4 2  0  1  3  4 
20

Si può semplicemente fare:

 
df[sorted(df.columns)] 
+1

Ottengo "l'oggetto DataFrame" non è richiamabile "per questo. Versione: panda 0.14. – multigoodverse

13

Non dimenticare di aggiungere "inplace = True" alla risposta di Wes o di impostare il risultato su un nuovo DataFrame.

df.sort_index(axis=1, inplace=True) 
3

Il metodo più rapido è:

df.sort_index(axis=1) 

essere consapevoli che questo crea una nuova istanza.Pertanto è necessario memorizzare il risultato in una nuova variabile:

sortedDf=df.sort_index(axis=1) 
-1
print df.sort_index(by='Frequency',ascending=False) 

in cui si trova il nome della colonna, se si desidera ordinare il set di dati in base a colonna

9

Se avete bisogno di un arbitrario sequenza invece di sequenza ordinata, si potrebbe fare:

sequence = ['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 
your_dataframe = your_dataframe.reindex(columns=sequence) 

Ho provato questo in 2.7.10 e ha funzionato per me.

5

Per diverse colonne, si può mettere le colonne ordinare quello che volete:

#['A', 'B', 'C'] <-this is your columns order 
df = df[['C', 'B', 'A']] 

Questo esempio mostra smistamento e affettatrici colonne:

d = {'col1':[1, 2, 3], 'col2':[4, 5, 6], 'col3':[7, 8, 9], 'col4':[17, 18, 19]} 
df = pandas.DataFrame(d) 

si ottiene:

col1 col2 col3 col4 
1  4  7 17 
2  5  8 18 
3  6  9 19 

Poi do:

df = df[['col3', 'col2', 'col1']] 

Con conseguente:

col3 col2 col1 
7  4  1 
8  5  2 
9  6  3  
0

Un caso d'uso è che si è chiamato (alcune) le colonne con un certo prefisso, e si desidera che le colonne ordinate con quei prefissi tutti insieme e in un certo ordine particolare (non alfabetico).

Ad esempio, è possibile avviare tutte le funzionalità con Ft_, etichette con Lbl_, ecc. E si desidera innanzitutto tutte le colonne non prefissate, quindi tutte le funzioni, quindi l'etichetta. È possibile farlo con la seguente funzione (Mi si nota un possibile problema di efficienza utilizzando sum a ridurre le liste, ma questo non è un problema a meno che non hai un sacco di colonne, che io non faccio):

def sortedcols(df, groups = ['Ft_', 'Lbl_']): 
    return df[ sum([list(filter(re.compile(r).search, list(df.columns).copy())) for r in (lambda l: ['^(?!(%s))' % '|'.join(l)] + ['^%s' % i for i in l ])(groups) ], []) ] 
Problemi correlati