Pandas: multiplicación elemental de dos marcos de datos

Sé cómo hacer la multiplicación elemento por elemento entre dos marcos de datos Pandas. Sin embargo, las cosas se complican cuando las dimensiones de los dos marcos de datos no son compatibles. Por ejemplo, a continuación df * df2 es sencillo, pero df * df3 es un problema:

 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 

En la situación anterior, ¿cómo puedo multiplicar cada columna de df con df3.col1 ?

Mi bash: intenté replicar los df3.col1 len(df.columns.values) para obtener un dataframe que sea de la misma dimensión que df :

 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 

Pero esto crea un dataframe de dimensiones 3 * 5, mientras que estoy después de 5 * 3. Sé que puedo tomar la transposición con df3.T() para obtener lo que necesito, pero creo que esta no es la forma más rápida.

 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 

Una forma más sencilla de hacer esto es simplemente multiplicar el dataframe cuyos nombres de usuario desea mantener con los valores (es decir, la matriz numpy) de la otra, de esta manera:

 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 

De esta manera, no tiene que escribir todo el nuevo cuadro de referencia del dataframe.

Esto funciona para mí:

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

O, cuando quieres restar (dividir) en su lugar:

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

También funciona con nan en df (por ejemplo, si aplica esto a df: df.iloc[0]['col2'] = np.nan)

Otra forma es crear una lista de columnas y unirlas:

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

Para utilizar las propiedades de transmisión de Pandas, puede utilizar multiply .

 df.multiply(df3['col1'], axis=0)