Там, где в столбце панд есть NaN, я хочу заменить его на 1, за исключением итоговых сумм, которые должны суммировать 1 - PullRequest
3 голосов
/ 30 сентября 2019

В столбце «Возврат месяца» мне нужно заменить NaN на 1, за исключением значений в столбце «Категория» на «ИТОГО». Мне нужно, чтобы они суммировали 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

Ответы [ 2 ]

3 голосов
/ 30 сентября 2019

Вы можете использовать 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
1 голос
/ 01 октября 2019

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. Имейте в виду, что при этом удаляются значения, в которых у нас уже было 'Month Return' в строке 'TOTAL'. Но это нормально, я немного пересчитаю.

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

Это дает мне серию, индекс которой соответствует моему фрейму данных, и упрощает fillna, потому что Панды будут знать, какие строки заполнить.

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

На данный момент единственными строками в ones, имеющими значения NaN, являются строки с 'TOTAL' в столбце 'Category'. И это именно те, которые я собираюсь заполнить суммой для каждого 'Account'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...