J'ai le dataframe suivant:

                'B'         'C'
1/1/2017    'A' 
            BTC NaN       0.367392
            ETH NaN       0.367392
            XRP 0.164735  0.164735
            LTC 0.100481  0.100481
1/2/2017    BTC NaN       0.315265
            XRP NaN       0.315265
            ETH NaN       0.315265
            LTC 0.054204  0.054204

Je veux redistribuer (1 - df ['B']. Groupby (level = 0) .sum ()) également entre les valeurs NaN. La colonne «C» est un exemple de sortie attendue.

2
rakamakafo 11 mars 2019 à 10:17

2 réponses

Meilleure réponse

Vous pouvez utiliser GroupBy.transform par le premier niveau de MultiIndex avec sum, pour le deuxième nombre de NaNs en vérifiant les valeurs manquantes par Series.isna avec sum, divisez et remplacez les valeurs manquantes :

print (df)
                     C         D
A        B                      
1/1/2017 BTC       NaN  0.367392
         ETH       NaN  0.367392
         XRP  0.164735  0.164735
         LTC  0.100481  0.100481
1/2/2017 BTC       NaN  0.315265
         XRP       NaN  0.315265
         ETH       NaN  0.315265
         LTC  0.054204  0.054204

sum1 = 1 - df['C'].groupby(level=0).transform('sum')
len1 = df['C'].isna().groupby(level=0).transform('sum')

df['E'] = df['C'].fillna(sum1 / len1)
print (df)
                     C         D         E
A        B                                
1/1/2017 BTC       NaN  0.367392  0.367392
         ETH       NaN  0.367392  0.367392
         XRP  0.164735  0.164735  0.164735
         LTC  0.100481  0.100481  0.100481
1/2/2017 BTC       NaN  0.315265  0.315265
         XRP       NaN  0.315265  0.315265
         ETH       NaN  0.315265  0.315265
         LTC  0.054204  0.054204  0.054204
0
jezrael 11 mars 2019 à 07:48

Cela devrait le faire. Vous pouvez obtenir plus d'informations sur la façon de compter les valeurs non nan à partir de ici et surisnull()de ici.

Quelle que soit la réponse que vous utilisez, détectez toujours le cas où une colonne n'a pas de valeur NaN. Dans ce cas, les deux réponses entraîneront une division par zéro erreur.

import pandas as pd
import numpy as np
test = [np.NAN,np.NAN,np.NAN,np.NAN,0.123128,0.1238123]
df = pd.DataFrame({"B":test})
df["C"] = df["B"].copy()
df["C"][df["C"].isnull()] = (1-df["B"].dropna().sum())/(len(df["B"]) - df["B"].count())
print(df)

Production:

          B         C
0       NaN  0.188265
1       NaN  0.188265
2       NaN  0.188265
3       NaN  0.188265
4  0.123128  0.123128
5  0.123812  0.123812
0
f.wue 11 mars 2019 à 08:59