Процентное изменение pandas с отсутствующими данными

Мне нужно получить процентное изменение нескольких столбцов.

import pandas as pd
t="""Year\tChild\tBehaviour
1987\tBoy\tGood
1987\tGirl\tGood
1987\tBoy\tBad
1987\tGirl\tBad
2020\tBoy\tBad
2020\tBoy\tBad
2020\tGirl\tBad
2020\tGirl\tBad"""
from io import StringIO
df=pd.read_table(StringIO(t))
pv=pd.crosstab(df["Child"], [df["Year"], df["Behaviour"]])
print(pv)
print(pv[2020]/pv[1987]-1)

В жестоком мире будущего больше нет хороших детей, и это проблема, потому что я получаю NaN вместо -1 (-100%):

Year      1987      2020
Behaviour  Bad Good  Bad
Child                   
Boy          1    1    2
Girl         1    1    2

Behaviour  Bad  Good
Child               
Boy          1   NaN
Girl         1   NaN

Как это можно решить в общем случае? Нужно ли заранее добавлять отсутствующие столбцы, заполненные нулями? Или есть другой способ получить процентное изменение


person Winand    schedule 13.02.2016    source источник
comment
Вероятно, проще всего убедиться, что у вас есть столбец «Хорошо» с нулями для этого года.   -  person joris    schedule 13.02.2016


Ответы (1)


Вероятно, вы захотите что-то подобное, используя fillna. метод?

>>> (pv[2020]/pv[1987]).fillna(0) - 1
Behaviour  Bad  Good
Child               
Boy          1    -1
Girl         1    -1

Другой способ — использовать параметр dropna=True из функции crosstab:

>>> pv = pd.crosstab(df["Child"], [df["Year"], df["Behaviour"]], dropna=False)
>>> pv
      1987      2020     
       Bad Good  Bad Good
Child                    
Boy      1    1    2    0
Girl     1    1    2    0

>>> pv[2020]/pv[1987] - 1
       Bad  Good
Child           
Boy      1    -1
Girl     1    -1
person Roman Pekar    schedule 13.02.2016
comment
спасибо, я не мог понять, как аргумент dropna влияет на результат. - person Winand; 13.02.2016
comment
dropna=False по какой-то причине отбрасывает имена уровней столбцов. Похоже на ошибку. - person Winand; 13.02.2016