2016-10-11 4 views
1

Ich versuche, einige Spalten eines Pandas DataFrame in Python zu ihrer Summe zu normalisieren. Ich habe folgende dem Datenrahmen:Python Pandas Dataframe Divisionsfehler: Operation nicht '' sicher ''

import pandas as pd 
l_a_2015 = ['Farh','Rob_Sens','Pressure','Septic',10.0,45.,52.,72.51] 
l_a_2010 = ['Water_Column','Log','Humid','Top_Tank',58.64,35.42,10.,30.] 

df = pd.DataFrame([l_a_2010,l_a_2015],columns=['Output_A','Tonnes_Rem', 
               'Log_Act_All','Readout','A1','A2','A3','A4']) 

I würde die Spalten normalisieren mag A1, A2, A3, A4 ihre Summe als here gezeigt - Unterteile jedes Element in einer Zeile durch die Summe aus 4 Elementen.

Der erste Teil dieses scheint gut zu funktionieren - ich die Summe der letzten 4 Spalten erhalten, in jeder Zeile, mit diesem:

x,y = df.sum(axis=1).tolist() 

So ist die Liste [x,y] gibt mir die Summe der ersten und zweite Zeilen (die letzten 4 Spalten). Allerdings, wenn ich durch die Summe dieser Reihe zu teilen alle Datenrahmen Einträge in jeder Zeile versuchen, dann bin ich mit Problemen:

for b,n in enumerate([x,y]): 
    for f,elem in enumerate(list(df)[4:]): 
     df.iloc[b,f] = (df.iloc[b,f]/n)*100. 

ich die folgende Fehlermeldung erhalten:

[Traceback (most recent call last):134.06, 179.50999999999999] 

    File "C:\test.py", line 13, in <module> 
    df.iloc[b,f] = (df.iloc[b,f]/n)*100. 
TypeError: ufunc 'divide' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

Als ich Verwenden Sie print df.dtypes Ich bekomme float64 für alle Spalten, so dass ich nicht sicher bin, warum die Abteilung nicht sicher ist.

Gibt es

Antwort

2

versuchen Sie dies:

In [5]: df 
Out[5]: 
     Output_A Tonnes_Rem Log_Act_All Readout  A1  A2 A3  A4 
0 Water_Column  Log  Humid Top_Tank 58.64 35.42 10.0 30.00 
1   Farh Rob_Sens Pressure Septic 10.00 45.00 52.0 72.51 

In [8]: cols = df.select_dtypes(include=['number']).columns.tolist() 

In [9]: cols 
Out[9]: ['A1', 'A2', 'A3', 'A4'] 

wir nur eine Ansicht mit numerischen Spalten erstellen:

In [10]: v = df[cols] 

In [13]: df[cols] = v.div(v.sum(axis=1), 0) 

In [14]: df 
Out[14]: 
     Output_A Tonnes_Rem Log_Act_All Readout  A1  A2  A3  A4 
0 Water_Column  Log  Humid Top_Tank 0.437416 0.264210 0.074593 0.223780 
1   Farh Rob_Sens Pressure Septic 0.055707 0.250682 0.289677 0.403933 

eine alternative Möglichkeit A* Spalten auszuwählen:

In [18]: df.filter(regex='^A\d+') 
Out[18]: 
     A1  A2  A3  A4 
0 0.437416 0.264210 0.074593 0.223780 
1 0.055707 0.250682 0.289677 0.403933 

In [19]: df.filter(regex='^A\d+').columns 
Out[19]: Index(['A1', 'A2', 'A3', 'A4'], dtype='object') 
+0

Vielen Dank! Tatsächlich habe ich gerade gemerkt, dass der Post, mit dem ich verlinkt habe ([hier] (http://stackoverflow.com/questions/18594469/normalizing-a-pandas-dataframe-by-row)) den gleichen Ansatz enthielt. Ich dachte nicht, dass das mit den nicht numerischen Spalten in meinem Datenrahmen funktionieren würde. Ihr Ansatz ist mit den Erklärungen intuitiver. Danke noch einmal! –