web-dev-qa-db-fra.com

Pandas: multiplication élément par élément de deux trames de données

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.col1len(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.

16
Zhubarb
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
28
unutbu

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.

10
The Unfun Cat

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)

3
Martien Lubberink

Pour utiliser Pandas propriétés de diffusion, vous pouvez utiliser multiply .

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

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:])
1
Andrey Shokhin