J'ai un df:

dates         p1     p2    p3    p4    
2019-12-01   0.4    0.4   0.4   0.3 
2019-12-02   0.41   0.3   0.3   0.3  

Et une constante df comme celle-ci :

   v1      v2      v3
0   43  0.680068  680.068
1  210  0.319932  319.932
2  211  0.319932  319.932

Je voudrais multiplier chaque élément du premier df par chaque valeur de v3 et créer un multi-index qui prend le v1 comme index de niveau supérieur - quelque chose qui ressemble à ceci :

                                 43                                 210  ...
dates            p1             p2         p3         p4       ...   p1 ...
2019-12-01   0.4 * 680.068    0.4* v3    0.4 * v3   0.3 * v3   ...  0.3 * 319.932 
2019-12-02   0.41 * v3   0.3 * v3   0.3 * v3  0.3 * v3   ...   ...  ... 

Cela donnerait donc 1 df avec 3 index de niveau supérieur (43, 210, 211), puis au niveau inférieur 3 dfs qui ont eu une multiplication élément par élément

0
Bob 15 févr. 2020 à 16:39

1 réponse

Meilleure réponse

Ceci est une simple extension de votre question précédente. Je supposerai toujours que dates est utilisé comme index pour la trame de données initiale, disons df :

              p1   p2   p3   p4
dates                          
2019-12-01  0.40  0.4  0.4  0.3
2019-12-02  0.41  0.3  0.3  0.3

Appelons v la deuxième trame de données et dg le résultat.

Nous pouvons simplement calculer les valeurs avec concat :

dg = pd.concat([df * val for val in v['v3']], axis = 1)

Ensuite, nous calculons le libellé des colonnes avec MultiIndex.from_products :

dg.columns = pd.MultiIndex.from_product([v['v1'], df.columns])

Obtenir:

                  43                                       210                                     211                             
                   p1        p2        p3        p4         p1        p2        p3       p4         p1        p2        p3       p4
dates                                                                                                                              
2019-12-01  272.02720  272.0272  272.0272  204.0204  127.97280  127.9728  127.9728  95.9796  127.97280  127.9728  127.9728  95.9796
2019-12-02  278.82788  204.0204  204.0204  204.0204  131.17212   95.9796   95.9796  95.9796  131.17212   95.9796   95.9796  95.9796

Cela peut même se faire en un seul passage (merci à anky_91 pour l'astuce) :

pd.concat([df * val for val in v['v3']], axis = 1,keys=v['v1'])

Un multiindex peut avoir des noms, vous pouvez donc même faire :

dg.columns.names=('v1', '')

Obtenir:

v1                43                                       210                                     211                             
                   p1        p2        p3        p4         p1        p2        p3       p4         p1        p2        p3       p4
dates                                                                                                                              
2019-12-01  272.02720  272.0272  272.0272  204.0204  127.97280  127.9728  127.9728  95.9796  127.97280  127.9728  127.9728  95.9796
2019-12-02  278.82788  204.0204  204.0204  204.0204  131.17212   95.9796   95.9796  95.9796  131.17212   95.9796   95.9796  95.9796
3
Serge Ballesta 15 févr. 2020 à 15:06