2017-11-29 1 views
1

ich einen Welt Indicator-Datensatz haben, die dieses Format hatZeilenweiser Betrieb in Pandas Datenrahmen

country  year indicatorName  value 
USA   1970 Agricultural Land ... 
USA   1970 Crop production  ... 
... 
USA   2000 Agricultural Land ... 
USA   2000 Crop production  ... 
... 
Mexico  1970 Agricultural Land ... 
Mexico  1970 Crop production  ... 
... 
Mexico  2000 Agricultural Land ... 
Mexico  2000 Crop production  ... 

Es gibt hier Indikatoren, dass ich nicht enthalten, aber diese beiden sind, was mich interessiert. Ich wollen die entsprechenden value von Crop production zu Agricultural Land per country per year teilen. Lassen Sie uns das Ergebnis crop_prod_density nennen.

Ich weiß nicht, wie von

df.groupby(['country', 'year']) 

fortzufahren Wie es von hier zu tun, die folgenden Ausgaben zur Folge:

  1. Neuen Reihe Indikator

country year indicatorName value USA 1970 Agricultural Land ... USA 1970 Crop production ... USA 1970 crop_prod_density ...

  1. hinzufügen neue Spalte mit gleichen Werten für alle Zeilen für gruppierte (Land, Jahr)

country year indicatorName value crop_prod_density USA 1970 Agricultural Land ... us_value_1970 USA 1970 Crop production ... us_value_1970 ... Mexico 2000 Agricultural Land ... mx_value_2000 Mexico 2000 Crop production ... mx_value_2000

  1. Neue Datenrahmen mit nur dieser Spalte für Werte

country year crop_prod_density USA 1970 us_value_1970 ... USA 2000 us_value_2000 ... Mexico 1970 mx_value_1970 ... Mexico 2000 mx_value_2000

Antwort

2

Sie können zunächst durch set_index mit unstack neu zu gestalten und teilen sich dann durch div:

print (df) 
    country year  indicatorName value 
0  USA 1970 Agricultural Land  10 
1  USA 1970 Crop production  2 
2  USA 2000 Agricultural Land  10 
3  USA 2000 Crop production  3 
4 Mexico 1970 Agricultural Land  10 
5 Mexico 1970 Crop production  5 
6 Mexico 2000 Agricultural Land  10 
7 Mexico 2000 Crop production  4 

df = (df.set_index(['country','year','indicatorName'])['value'] 
     .unstack() 
     .assign(crop_prod_density=lambda x: x['Crop production'].div(x['Agricultural Land']))) 
print (df) 
indicatorName Agricultural Land Crop production crop_prod_density 
country year               
Mexico 1970     10    5    0.5 
     2000     10    4    0.4 
USA  1970     10    2    0.2 
     2000     10    3    0.3 

Dann umformen zurück durch stack:

df1 = df.stack().reset_index(name='value') 
print (df1) 
    country year  indicatorName value 
0 Mexico 1970 Agricultural Land 10.0 
1 Mexico 1970 Crop production 5.0 
2 Mexico 1970 crop_prod_density 0.5 
3 Mexico 2000 Agricultural Land 10.0 
4 Mexico 2000 Crop production 4.0 
5 Mexico 2000 crop_prod_density 0.4 
6  USA 1970 Agricultural Land 10.0 
7  USA 1970 Crop production 2.0 
8  USA 1970 crop_prod_density 0.2 
9  USA 2000 Agricultural Land 10.0 
10  USA 2000 Crop production 3.0 
11  USA 2000 crop_prod_density 0.3 

Für neue Spalte original append zu indizieren neue Spalte, aber zuletzt ist notwendig, Änderung der Reihenfolge der Spalten von reindex:

df2 =(df.set_index(['crop_prod_density'], append=True) 
     .stack() 
     .reset_index(name='value') 
     .reindex(columns=['country','year','indicatorName','value','crop_prod_density'])) 
print (df2) 
    country year  indicatorName value crop_prod_density 
0 Mexico 1970 Agricultural Land  10    0.5 
1 Mexico 1970 Crop production  5    0.5 
2 Mexico 2000 Agricultural Land  10    0.4 
3 Mexico 2000 Crop production  4    0.4 
4  USA 1970 Agricultural Land  10    0.2 
5  USA 1970 Crop production  2    0.2 
6  USA 2000 Agricultural Land  10    0.3 
7  USA 2000 Crop production  3    0.3 

Und last Entfernen Sie unnötige Spalten und erstellen Sie Spalten von MultiIndex:

df3 = (df.drop(['Crop production','Agricultural Land'], axis=1) 
     .reset_index() 
     .rename_axis(None, 1)) 
print (df3) 
    country year crop_prod_density 
0 Mexico 1970    0.5 
1 Mexico 2000    0.4 
2  USA 1970    0.2 
3  USA 2000    0.3