2014-01-09 12 views
11

Ich weiß, wie Element-für-Element-Multiplikation zwischen zwei Pandas-Datenrahmen zu tun. Die Dinge werden jedoch komplizierter, wenn die Dimensionen der beiden Datenrahmen nicht kompatibel sind. Zum Beispiel unter df * df2 einfach ist, aber df * df3 ist ein Problem:Pandas: Elementweise Multiplikation von zwei Datenrahmen

df = pd.DataFrame({'col1' : [1.0] * 5, 
        'col2' : [2.0] * 5, 
        'col3' : [3.0] * 5 }, index = range(1,6),) 
df2 = pd.DataFrame({'col1' : [10.0] * 5, 
        'col2' : [100.0] * 5, 
        'col3' : [1000.0] * 5 }, index = range(1,6),) 
df3 = pd.DataFrame({'col1' : [0.1] * 5}, index = range(1,6),) 

df.mul(df2, 1) # element by element multiplication no problems 

df.mul(df3, 1) # df(row*col) is not equal to df3(row*col) 
    col1 col2 col3 
1 0.1 NaN NaN 
2 0.1 NaN NaN 
3 0.1 NaN NaN 
4 0.1 NaN NaN 
5 0.1 NaN NaN 

In der obigen Situation wie kann ich jede Spalte von df mit df3.col1 multiplizieren?

Mein Versuch: Ich versuchte df3.col1len(df.columns.values) mal zu replizieren, um einen Datenrahmen zu erhalten, die als df die gleichen Dimension ist:

df3 = pd.DataFrame([df3.col1 for n in range(len(df.columns.values)) ]) 
df3 
     1 2 3 4 5 
col1 0.1 0.1 0.1 0.1 0.1 
col1 0.1 0.1 0.1 0.1 0.1 
col1 0.1 0.1 0.1 0.1 0.1 

Aber das schafft eine Datenrahmen von Dimensionen 3 * 5, während ich bin nach 5 * 3. Ich weiß, dass ich die Transponierung mit df3.T() nehmen kann, um zu bekommen, was ich brauche, aber ich denke, das ist nicht der schnellste Weg.

Antwort

22
In [161]: pd.DataFrame(df.values*df2.values, columns=df.columns, index=df.index) 
Out[161]: 
    col1 col2 col3 
1 10 200 3000 
2 10 200 3000 
3 10 200 3000 
4 10 200 3000 
5 10 200 3000 
+0

Danke unutbu. 'pd.DataFrame (df.values ​​* df3.values, Spalten = df.columns, index = df.index)' behält den Index auch, richtig? – Rhubarb

+0

Ja, das stimmt. – unutbu

1

Ein anderer Weg ist die Liste der Spalten erstellen und sich ihnen anzuschließen:

cols = [pd.DataFrame(df[col] * df3.col1, columns=[col]) for col in df] 
mul = cols[0].join(cols[1:]) 
7

Ein einfacher Weg, dies zu tun, ist nur die Datenrahmen, dessen sich zu vermehren COLNAMES Sie wollen mit den Werten halten (dh numpy Array) des anderen, etwa so:

In [63]: df * df2.values 
Out[63]: 
    col1 col2 col3 
1 10 200 3000 
2 10 200 3000 
3 10 200 3000 
4 10 200 3000 
5 10 200 3000 

auf diese Weise müssen Sie all diese neuen Datenrahmen vorformulierten nicht schreiben.

1

Dies funktioniert für mich:

mul = df.mul(df3.c, axis=0) 

Oder wenn Sie subtrahieren wollen (divide) statt:

sub = df.sub(df3.c, axis=0) 
div = df.div(df3.c, axis=0) 

Arbeiten auch mit einem nan in df (zB wenn Sie dies die Anwendung df: df.iloc[0]['col2'] = np.nan)