如果熊猫列中有 NaN,我想用 1 替换,除了需要对 1 求和的总计



在月份回报列中,我需要将 NaN 替换为 1,除了类别列中的 ros 与"总计"。我需要这些来总结上一个"总计"行之后的 1。分组行的长度(按日期和帐户(可能因长度而异。

Return Date    Account      Category    Month Return
7/31/2003      abcdef       BOND        NaN
7/31/2003      abcdef       CASH        NaN
7/31/2003      abcdef       EQUITY      NaN
7/31/2003      abcdef       TOTAL       Nan
7/31/2003      ghijkl       BOND        0.25
7/31/2003      ghijkl       CASH        0.25
7/31/2003      ghijkl       EQUITY      1.25
7/31/2003      ghijkl       TOTAL       1.75
7/31/2003      mnopqr       BOND        NaN
7/31/2003      mnopqr       CASH        NaN
7/31/2003      mnopqr       EQUITY      NaN
7/31/2003      mnopqr       REAL        NaN
7/31/2003      mnopqr       TOTAL       Nan

希望它看起来像这样:

Return Date    Account      Category    Month Return
7/31/2003      abcdef       BOND        1
7/31/2003      abcdef       CASH        1
7/31/2003      abcdef       EQUITY      1
7/31/2003      abcdef       TOTAL       3
7/31/2003      ghijkl       BOND        0.25
7/31/2003      ghijkl       CASH        0.25
7/31/2003      ghijkl       EQUITY      1.25
7/31/2003      ghijkl       TOTAL       1.75
7/31/2003      mnopqr       BOND        1
7/31/2003      mnopqr       CASH        1
7/31/2003      mnopqr       EQUITY      1
7/31/2003      mnopqr       REAL        1
7/31/2003      mnopqr       TOTAL       4

您可以将 DataFrame.fillna 与 DataFrame.loc 一起使用:

df=df.replace('Nan',np.nan)
c=df['Category'].ne('TOTAL')
df.loc[c,'Month_Return']=df.loc[c,'Month_Return'].fillna(1)
fill=df.groupby('Account')['Month_Return'].apply(lambda x: x.eq(1).cumsum())
df['Month_Return'].fillna(fill,inplace=True)
print(df)
Return_Date Account Category Month_Return
0    7/31/2003  abcdef     BOND            1
1    7/31/2003  abcdef     CASH            1
2    7/31/2003  abcdef   EQUITY            1
3    7/31/2003  abcdef    TOTAL            3
4    7/31/2003  ghijkl     BOND         0.25
5    7/31/2003  ghijkl     CASH         0.25
6    7/31/2003  ghijkl   EQUITY         1.25
7    7/31/2003  ghijkl    TOTAL         1.75
8    7/31/2003  mnopqr     BOND            1
9    7/31/2003  mnopqr     CASH            1
10   7/31/2003  mnopqr   EQUITY            1
11   7/31/2003  mnopqr     REAL            1
12   7/31/2003  mnopqr    TOTAL            4

transform混在某个地方

mask = df['Category'].eq('TOTAL')
ones = df['Month Return'].fillna(1).mask(mask)
tots = ones.groupby(df['Account']).transform('sum')
df['Month Return'] = ones.fillna(tots)
df
Return Date Account Category  Month Return
0    7/31/2003  abcdef     BOND          1.00
1    7/31/2003  abcdef     CASH          1.00
2    7/31/2003  abcdef   EQUITY          1.00
3    7/31/2003  abcdef    TOTAL          3.00
4    7/31/2003  ghijkl     BOND          0.25
5    7/31/2003  ghijkl     CASH          0.25
6    7/31/2003  ghijkl   EQUITY          1.25
7    7/31/2003  ghijkl    TOTAL          1.75
8    7/31/2003  mnopqr     BOND          1.00
9    7/31/2003  mnopqr     CASH          1.00
10   7/31/2003  mnopqr   EQUITY          1.00
11   7/31/2003  mnopqr     REAL          1.00
12   7/31/2003  mnopqr    TOTAL          4.00

mask = df['Category'].eq('TOTAL')

我将使用它来清除maskTrue的值,但我希望我的代码更漂亮。

ones = df['Month Return'].fillna(1) ...

这是我用1填充缺失位的地方

ones = df['Month Return'].fillna(1).mask(mask)

然后涂抹掉maskTrueCategoryTOTAL的行。 请记住,这会删除我们在'TOTAL'行中已有'Month Return'的值。 不过没关系,我一会儿再计算。

tots = ones.groupby(df['Account']).transform('sum')

这让我得到一个索引与我的数据帧匹配的序列,并且更容易fillna,因为 Pandas 会知道要填充哪些行。

df['Month Return'] = ones.fillna(tots)

此时,ones中唯一具有NaN值的行是'Category'列中具有'TOTAL'的行。 而这些正是那些,我将用每'Account'的总和来填充.

最新更新