Je sais comment multiplier élément par élément entre deux Pandas dataframes. Cependant, les choses se compliquent lorsque les dimensions des deux dataframes ne sont pas compatibles. Par exemple ci-dessous df * df2
Est simple, mais df * df3
est un problème:
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
Dans la situation ci-dessus, comment puis-je multiplier chaque colonne de df par df3.col1?
Ma tentative: J'ai essayé de répliquer df3.col1
len(df.columns.values)
fois pour obtenir une trame de données de la même dimension 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
Mais cela crée un dataframe de dimensions 3 * 5, alors que je suis après 5 * 3. Je sais que je peux prendre la transposition avec df3.T()
pour obtenir ce dont j'ai besoin mais je pense que ce n'est pas le moyen le plus rapide.
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
Une façon plus simple de le faire est simplement de multiplier la trame de données dont vous souhaitez conserver les noms de colonnes avec les valeurs (c'est-à-dire le tableau numpy) de l'autre, comme ceci:
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 cette façon, vous n'avez pas à écrire tout ce nouveau passe-partout de trame de données.
Cela fonctionne pour moi:
mul = df.mul(df3.c, axis=0)
Ou, lorsque vous souhaitez soustraire (diviser) à la place:
sub = df.sub(df3.c, axis=0)
div = df.div(df3.c, axis=0)
Fonctionne également avec un nan
dans df (par exemple, si vous appliquez ceci au df: df.iloc[0]['col2'] = np.nan)
Pour utiliser Pandas propriétés de diffusion, vous pouvez utiliser multiply
.
df.multiply(df3['col1'], axis=0)
Une autre façon est de créer une liste de colonnes et de les joindre:
cols = [pd.DataFrame(df[col] * df3.col1, columns=[col]) for col in df]
mul = cols[0].join(cols[1:])