2017-10-18 7 views
0

J'ai un df1 qui ressemble à:Comment puis-je transformer deux trames de données en une autre?

   Shady Slim Eminem 
Date       
2011-01-10 HI  Yes 1500 
2011-01-13 HI  No 1500 
2011-01-13 BYBY Yes 4000 
2011-01-26 OKDO Yes 1000 

Je df2 qui ressemble à ceci:

   HI  BYBY OKDO  INT 
Date             
2011-01-10 340.99 143.41 614.21  1.0 
2011-01-13 344.20 144.55 616.69  1.0 
2011-01-13 344.20 144.55 616.69  1.0 
2011-01-26 342.38 156.42 616.50  1.0 

Je veux sauver Eminem comme série. Je veux également que chaque colonne de df2 soit une série. Je veux multiplier Eminem par ces valeurs dans les bons éléments correspondants de Shady et remplir df3. Je veux un df3 qui ressemble

Je veux aussi la colonne INT à la somme des lignes pour chaque ligne de df3.

Je veux cela d'une manière de vectorisation.

En outre, basé sur la colonne SLIM, si c'est YES alors je veux ajouter le Eminem * value sinon je veux la négation de celui-ci.

Voici les valeurs que je veux:

   HI  BYBY OKDO  INT 
Date             
2011-01-10 511,485  0  0 sum(row 1) 
2011-01-13 -516300 578200 0 sum(row 2) 
2011-01-13 0   578200 0 sum(row 3) 
2011-01-26 0   0  616500 sum(row 4) 

Répondre

1

Option 1
Utilisez la méthode pd.DataFrame.mul pour multiplier et fournir un paramètre axis afin de spécifier que vous voulez que la série vous multipliez par être alignés le long de l'index.

df2.mul(df1.Eminem, axis=0) 

        HI  BYBY  OKDO  SOME  COOL  INT 
Date                 
2011-01-10 511485.0 215115.0 921315.0 108030.0 184785.0 1500.0 
2011-01-13 516300.0 216825.0 925035.0 110310.0 186810.0 1500.0 
2011-01-13 1376800.0 578200.0 2466760.0 294160.0 498160.0 4000.0 
2011-01-26 342380.0 156420.0 616500.0 76370.0 125800.0 1000.0 

Option 2
Si par hasard, la série dans laquelle vous essayez de multiplier par est déjà ordonné à la façon dont vous souhaitez multiplier, vous pouvez renoncer à l'index et l'accès l'attribut values.

df2.mul(df1.Eminem.values, 0) 

        HI  BYBY  OKDO  SOME  COOL  INT 
Date                 
2011-01-10 511485.0 215115.0 921315.0 108030.0 184785.0 1500.0 
2011-01-13 516300.0 216825.0 925035.0 110310.0 186810.0 1500.0 
2011-01-13 1376800.0 578200.0 2466760.0 294160.0 498160.0 4000.0 
2011-01-26 342380.0 156420.0 616500.0 76370.0 125800.0 1000.0 

Option 3
Si l'index se révèle difficile, vous pouvez ajouter un niveau qui le rend unique

unique_me = lambda d: d.set_index(d.groupby(level=0).cumcount(), append=True) 
df2.pipe(unique_me).mul(df1.pipe(unique_me).Eminem, axis=0).reset_index(-1, drop=True) 

        HI  BYBY  OKDO  SOME  COOL  INT 
Date                 
2011-01-10 511485.0 215115.0 921315.0 108030.0 184785.0 1500.0 
2011-01-13 516300.0 216825.0 925035.0 110310.0 186810.0 1500.0 
2011-01-13 1376800.0 578200.0 2466760.0 294160.0 498160.0 4000.0 
2011-01-26 342380.0 156420.0 616500.0 76370.0 125800.0 1000.0 

Avec Slim Factor

df2.drop('INT', axis=1, errors='ignore').mul(df1.Eminem.values, 0).assign(
    INT=lambda d: (lambda s: s.mask(df1.Slim.eq('No'), -s))(d.sum(1))) 

        HI  BYBY  OKDO  SOME  COOL  INT 
Date                  
2011-01-10 511485.0 215115.0 921315.0 108030.0 184785.0 1940730.0 
2011-01-13 516300.0 216825.0 925035.0 110310.0 186810.0 -1955280.0 
2011-01-13 1376800.0 578200.0 2466760.0 294160.0 498160.0 5214080.0 
2011-01-26 342380.0 156420.0 616500.0 76370.0 125800.0 1317470.0 
+0

Une dernière chose est le facteur 'Slim'. – dirtysocks45

+0

Les chiffres sont tous corrects sauf pour 'INT'. Pour int, si c'est un «NON», je veux la négation de la somme des autres éléments de cette rangée. Sinon, je veux que ce soit la somme positive des lignes. – dirtysocks45

+0

J'ai donné un exemple de ce dont j'avais besoin. – dirtysocks45