在月份回报列中,我需要将 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')
我将使用它来清除mask
True
的值,但我希望我的代码更漂亮。
ones = df['Month Return'].fillna(1) ...
这是我用1
填充缺失位的地方
ones = df['Month Return'].fillna(1).mask(mask)
然后涂抹掉mask
True
或Category
TOTAL
的行。 请记住,这会删除我们在'TOTAL'
行中已有'Month Return'
的值。 不过没关系,我一会儿再计算。
tots = ones.groupby(df['Account']).transform('sum')
这让我得到一个索引与我的数据帧匹配的序列,并且更容易fillna
,因为 Pandas 会知道要填充哪些行。
df['Month Return'] = ones.fillna(tots)
此时,ones
中唯一具有NaN
值的行是'Category'
列中具有'TOTAL'
的行。 而这些正是那些,我将用每'Account'
的总和来填充.