2016-03-22 2 views
-1

Ich habe es geschafft, das gewünschte Endergebnis zu bekommen, aber es muss einen effizienteren Weg geben, dies zu tun. Lassen Sie mich Sie durchgehen:Eine effizientere Route

Ich habe 100 Spalten von Meinungsdaten in Bezug auf 20 Kategorien.

This is what the data looks like

Im Bild oben Gesundheit und Arbeits sind 2 der 20 Kategorien. Die Kandidaten werden gebeten, die persönliche Wichtigkeit jeder Kategorie zu bewerten. Entweder stimmen sie stark nicht zu (1), stimmen nicht zu (2), keine Meinung (3), stimmen zu (4) oder stimmen völlig zu (5).

Was ich will, ist für eine neue Spalte für jede Kategorie erstellt werden und die Werte zu stapeln, so dass es eine Spalte mit den Antworten des Kandidaten gibt, anstatt verteilt über 5 Spalten. Es wurde festgelegt, dass kein Kandidat zwei Antworten für eine Kategorie gegeben hat. Die grünen Säulen im obigen Bild zeigen das gewünschte Ergebnis.

Hier ist die ineffiziente Weg, den ich gemacht habe:

Die Daten sind eine CSV-Datei in Verwendung Pandas lesen.

habe ich eine Liste für jede Kategorie, so 20 Listen:

df.columns 
health = list([col for col in df.columns if 'HEALTH' in col]) 
job = list([col for col in df.columns if 'JOB' in col]) 

Ich habe dann 20 neue Spalten in den Datenrahmen, der den Maximalwert von Spalten in der zugehörigen Liste unter Verwendung von Code nimmt.

Der letzte Schritt ist, diese 100 ursprünglichen Spalten zu löschen und nur die 20 neuen einzelnen Spalten mit allen Antworten der Kandidaten gestapelt zu haben.

Dies wurde unter Verwendung einer Liste der ursprünglichen Meinung Spalten mit dem Code getan:

df.drop(df[op_cols], axis=1, inplace=True) 
df.info() 

ich mich 2.7 so irgendwelche Ratschläge python lehre/Vorschläge, wie würden diese Schritte effizienter machen sehr geschätzt .

+0

Nun, zunächst einmal, 'Liste ([Spalte für Spalte in df.columns wenn‚Gesundheit‘in Spalte])' ist überflüssig ; Das Listenverständnis erzeugt eine "Liste", dann nimmt der "Listen" -Konstruktor diese "Liste", seicht es ab, gibt eine neue "Liste" zurück, und die ursprüngliche "Liste" wird zerstört. Entferne die 'list()' um beide listcomps und lass Python die 'list' direkt nur einmal konstruieren. – ShadowRanger

Antwort

0

Betrachten Sie einen Umformprozess mit Pandas 'wide_to_long(). Sie müssen einen numerischen Wert eingeben, hier key für die Ausgabe. Natürlich letzte Spalten (ohne Unterstrich) benennen und Art wie nach Kategorie benötigt:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'RESPID': [1,1,1,1,1], 
        'HEALTH_SD': [1,np.nan, np.nan, np.nan, np.nan], 
        'HEALTH_D': [np.nan, 2, np.nan, np.nan, np.nan], 
        'HEALTH_N': [np.nan, np.nan, 3, np.nan, np.nan], 
        'HEALTH_A': [np.nan, np.nan, np.nan, 4, np.nan], 
        'HEALTH_SA': [np.nan, np.nan, np.nan, np.nan, 5], 
        'JOB_SD': [1, np.nan, np.nan, np.nan, np.nan], 
        'JOB_D': [np.nan, 3, np.nan, np.nan, np.nan], 
        'JOB_N': [np.nan, np.nan, 2, np.nan, np.nan], 
        'JOB_A': [np.nan, np.nan, np.nan, 5, np.nan], 
        'JOB_SA': [np.nan, np.nan, np.nan, np.nan, 4]}) 
print df[['RESPID', 'HEALTH_SD', 'HEALTH_D', 'HEALTH_N', 'HEALTH_A', 'HEALTH_SA', 
     'JOB_SD', 'JOB_D', 'JOB_N', 'JOB_A', 'JOB_SA']] 
# RESPID HEALTH_SD HEALTH_D HEALTH_N HEALTH_A HEALTH_SA JOB_SD JOB_D JOB_N JOB_A JOB_SA 
#0  1   1  NaN  NaN  NaN  NaN  1 NaN NaN NaN  NaN 
#1  1  NaN   2  NaN  NaN  NaN  NaN  3 NaN NaN  NaN 
#2  1  NaN  NaN   3  NaN  NaN  NaN NaN  2 NaN  NaN 
#3  1  NaN  NaN  NaN   4  NaN  NaN NaN NaN  5  NaN 
#4  1  NaN  NaN  NaN  NaN   5  NaN NaN NaN NaN  4 

df['KEY'] = 1 
rdf = pd.wide_to_long(df, ['HEALTH_', 'JOB_'], i='RESPID', j='CATEG').dropna().reset_index()  
print rdf 

# RESPID CATEG KEY HEALTH_ JOB_ 
#0  1  A 1  4  5 
#1  1  D 1  2  3 
#2  1  N 1  3  2 
#3  1 SA 1  5  4 
#4  1 SD 1  1  1