2017-07-31 5 views
4

I ont deux pandas trame de données que je veux multiplier:Comment puis-je multiplier un DataFrame n * m avec un DataFrame 1 m dans un pandas?

frame_score: 
    Score1 Score2 
0  100  80 
1 -150  20 
2 -110  70 
3  180  99 
4  125  20 

frame_weights: 
    Score1 Score2 
0  0.6  0.4 

I ont essayé:

import pandas as pd 
import numpy as np 

frame_score = pd.DataFrame({'Score1' : [100, -150, -110, 180, 125], 
         'Score2' : [80, 20, 70, 99, 20]}) 

frame_weights = pd.DataFrame({'Score1': [0.6], 'Score2' : [0.4]}) 

print('frame_score: \n{0}'.format(frame_score)) 
print('\nframe_weights: \n{0}'.format(frame_weights)) 

# Each of the following alternatives yields the same results 
frame_score_weighted = frame_score.mul(frame_weights, axis=0) 
frame_score_weighted = frame_score * frame_weights 
frame_score_weighted = frame_score.multiply(frame_weights, axis=1) 

print('\nframe_score_weighted: \n{0}'.format(frame_score_weighted)) 

retours:

frame_score_weighted: 
    Score1 Score2 
0 60.0 32.0 
1  NaN  NaN 
2  NaN  NaN 
3  NaN  NaN 
4  NaN  NaN 

Les lignes 1 à 4 sont NaN. Comment puis-je éviter cela? Par exemple, la ligne 1 doit être -90 8 (-90 = -150 * 0,6; 8 = 20 * 0,4).

Par exemple, Numpy peut diffuser pour faire correspondre les dimensions.

Répondre

3

Edit: pour la dimension arbitraire, essayez d'utiliser values pour manipuler les valeurs des dataframes d'une manière semblable à un tableau:

# element-wise multiplication 
frame_score_weighted = frame_score.values*frame_weights.values 

# change to pandas dataframe and rename columns 
frame_score_weighted = pd.DataFrame(data=frame_score_weighted, columns=['Score1','Score2']) 

#Out: 
    Score1 Score2 
0 60.0 32.0 
1 -90.0  8.0 
2 -66.0 28.0 
3 108.0 39.6 
4 75.0  8.0 

il suffit d'utiliser une indexation supplémentaire pour vous assurer d'extraire les poids désirés comme un scalaire quand vous faites la multiplication.

frame_score['Score1'] = frame_score['Score1']*frame_weights['Score1'][0] 
frame_score['Score2'] = frame_score['Score2']*frame_weights['Score2'][0] 

frame_score 
#Out: 
    Score1 Score2 
0 60.0 32.0 
1 -90.0  8.0 
2 -66.0 28.0 
3 108.0 39.6 
4 75.0  8.0 
2

Par défaut, lorsque pd.DataFrame est multipliée par un pd.Series, pandas aligne l'indice de la pd.Series avec les colonnes de la pd.DataFrame. Ainsi, nous obtenons le pd.Series pertinent de frame_weights en accédant seulement à la première rangée.

frame_score * frame_weights.loc[0] 

    Score1 Score2 
0 60.0 32.0 
1 -90.0  8.0 
2 -66.0 28.0 
3 108.0 39.6 
4 75.0  8.0 

Vous pouvez modifier frame_score en place avec

frame_score *= frame_weights.loc[0]