2016-03-30 4 views
1

Ich schreibe gerade eine Reihe von Tabellentransformationsanweisungen in Postgres, für die ich in Python eine Funktion schreiben möchte, um die Anzahl der Wiederholungen zu reduzieren Code habe ich. Angenommen, ich eine Tabelle, die ich in Pandas laden, die so etwas wie folgt aussieht:Verwandle einen Datenrahmen Wide in Long und verwende eine Map (Python 3.5.1 Pandas)

import pandas as pd 
df = {'state' : ['NJ', 'NJ', 'NY', 'NY'], 
     'county' : ['AAA', 'BBB', 'CCC', 'DDD'], 
     'population' : [100, 200, 300, 400], 
     'other' : [11, 12, 13, 14], 
     'row_number': [1, 2, 3, 4] 
    } 


    county other population row_number state 
0 AAA  11   100   1  NJ 
1 BBB  12   200   2  NJ 
2 CCC  13   300   3  NY 
3 DDD  14   400   4  NY 

Ich möchte den Staat und Landkreis Spalten halten. Das Feld other und population repräsentiert tatsächliche Datenfelder. Am Ende möchte ich diese Werte in Excel-Tabellenspalten und Zeilen abbilden. Das Feld row_number stellt die Zeilennummer dar, die dem Bundesland und dem Bundesland entspricht.

Nun nehme ich an, ich habe ein Wörterbuch, das die "Zuordnung" zwischen den beiden Datenfeldern zu Spalten hat. Sagen wir, es sieht aus wie

column_mapping = {'other': 'A', 
        'population': 'B' 
       } 

ich einen Datenrahmen erzeugen möchten, die wie folgt aussieht:

county state   value   row 
0 AAA  NJ   11   A1   
1 AAA  NJ   100   B1 
2 BBB  NJ   12   A2 
3 BBB  NJ   200   B2   
4 CCC  NY   13   A3  
5 CCC  NY   300   B3  
6 DDD  NY   14   A4 
7 DDD  NY   400   B4 

zweitrangig, ich versuche, dies in der allgemeinsten Weise möglich zu tun, weil ich will um mehrere verschiedene Tabellen in diese Funktion mit ähnlicher Struktur zu übergeben, aber möglicherweise unterschiedliche Spaltennamen (state, county und row_number werden immer gleich sein, aber die tatsächlichen Datenfelder können unterschiedlich sein).

Antwort

2

können Sie melt verwenden zum Umformen, dann map Spalte variable, kombinieren Spalten mit Guss Integer-Spalte zu bespannen von astype und letzten drop unnötigen Spalten:

column_mapping = {'other': 'A', 
        'population': 'B' 
       } 

df = pd.melt(df, id_vars=['county','state', 'row_number'], 
       value_vars=['other', 'population']) 

df['variable'] = df['variable'].map(column_mapping) 
df['row'] = df['variable'] + df['row_number'].astype(str) 

df = df.drop(['variable','row_number'], axis=1) 

#if you need sort by county column with reset index 
df = df.sort_values('county').reset_index(drop=True) 
print df 
    county state value row 
0 AAA NJ  11 A1 
1 AAA NJ 100 B1 
2 BBB NJ  12 A2 
3 BBB NJ 200 B2 
4 CCC NY  13 A3 
5 CCC NY 300 B3 
6 DDD NY  14 A4 
7 DDD NY 400 B4 

EDIT:

Wenn Sie verwenden melt allgemeiner, unterlassen value_vars:

df = pd.melt(df, id_vars=['county','state', 'row_number']) 
df['variable'] = df['variable'].map(column_mapping) 
df['row'] = df['variable'] + df['row_number'].astype(str) 
df = df.drop(['variable','row_number'], axis=1) 
df = df.sort_values('county').reset_index(drop=True) 
print df 
    county state value row 
0 AAA NJ  11 A1 
1 AAA NJ 100 B1 
2 BBB NJ  12 A2 
3 BBB NJ 200 B2 
4 CCC NY  13 A3 
5 CCC NY 300 B3 
6 DDD NY  14 A4 
7 DDD NY 400 B4 
+0

Danke! Das funktioniert meistens für mich, aber ich bekomme einen wirklich seltsamen Fehler. Ich verwende 'pd.read_sql', um eine Abfrage auszuführen und einen DataFrame zurückzugeben. Wenn ich dies tue, erhalte ich einen Fehler: 'frame = frame.ix [:, id_vars + value_vars]' 'AttributError: 'tuple' Objekt hat kein Attribut 'ix''. Aber wenn ich 'pd.read_sql_table' direkt benutze, bekomme ich diesen Fehler nicht. Irgendwelche Ideen? – Vincent

+0

Sehr schwierige Frage. Sind 'Dataframes' gleich und benutzen' pd.read_sql' und 'pd.read_sql_table'? Sind 'Indizes' gleich? Oder eine enthält "Multiindex" und andere "Index"? – jezrael

+0

Nach vielen Stunden merke ich, dass ich ein zusätzliches Komma in der Mitte meines Codes hängen hatte = [[[[[ – Vincent

Verwandte Themen