Pandas: ERRO: groupby.pct_change () não funciona corretamente no Pandas 0.23.0. O agrupamento é ignorado.

Criado em 25 mai. 2018  ·  4Comentários  ·  Fonte: pandas-dev/pandas

Amostra de Código

>>>import pandas as pd
>>>import numpy as np

>>>df = pd.DataFrame(data=np.random.rand(8, 1), columns={'a'})
>>>df['grp']=1
>>>df.loc[::2, 'grp']=2
>>>df['%_groupby']=df.groupby('grp')['a'].pct_change()
>>>df['%_shift']=df.groupby('grp')['a'].shift(0)/df.groupby('grp')['a'].shift(1)-1
>>>print(df)

Descrição do Problema

Quando existem grupos diferentes em um dataframe, usando groupby espera-se que a função pct_change seja aplicada em cada grupo. No entanto, combinar groupby com pct_change não produz o resultado correto.

Resultado:

     a  grp  %_groupby   %_shift
0  1.0    2        NaN       NaN
1  1.1    1   0.100000       NaN
2  1.2    2   0.090909  0.200000
3  1.3    1   0.083333  0.181818
4  1.4    2   0.076923  0.166667
5  1.5    1   0.071429  0.153846
6  1.6    2   0.066667  0.142857
7  1.7    1   0.062500  0.133333

Resultado Esperado

     a  grp  %_groupby   %_shift
0  1.0    2        NaN       NaN
1  1.1    1        NaN       NaN
2  1.2    2   0.200000  0.200000
3  1.3    1   0.181818  0.181818
4  1.4    2   0.166667  0.166667
5  1.5    1   0.153846  0.153846
6  1.6    2   0.142857  0.142857
7  1.7    1   0.133333  0.133333

Resultado de pd.show_versions()

VERSÕES INSTALADAS


commit: Nenhum
python: 3.6.3.final.0
python-bits: 64
OS: Darwin
Versão do sistema operacional: 17.5.0
máquina: x86_64
processador: i386
byteorder: pouco
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.23.0
pytest: 3.2.1
pip: 10.0.1
setuptools: 36.5.0.post20170921
Cython: 0.26.1
numpy: 1.14.3
scipy: 0.19.1
pyarrow: Nenhum
xarray: Nenhum
IPython: 6.1.0
esfinge: 1.6.3
patsy: 0.4.1
dateutil: 2.6.1
pytz: 2018.3
blosc: nenhum
gargalo: 1.2.1
tabelas: 3.4.2
numexpr: 2.6.2
pena: nenhuma
matplotlib: 2.1.0
openpyxl: 2.4.8
xlrd: 1.1.0
xlwt: 1.2.0
xlsxwriter: 1.0.2
lxml: 4.1.1
bs4: 4.6.0
html5lib: 0,9999999
sqlalchemy: 1.1.13
pymysql: Nenhum
psycopg2: Nenhum
jinja2: 2.9.6
s3fs: nenhum
fastparquet: nenhum
pandas_gbq: Nenhum
pandas_datareader: Nenhum

Bug Groupby

Comentários muito úteis

Uma solução alternativa para isso é usar apply . Isso deve produzir o resultado desejado:

df['%_groupby'] = df.groupby('grp')['a'].apply(lambda x: x.pct_change())

Todos 4 comentários

Posso ver que a função pct_change em groupby.py na linha ~ 3944 não está implementando isso corretamente. Considerando que o método que ele substitui o implementa corretamente para um dataframe. Eu gostaria de pensar que isso deveria ser relativamente simples de remediar.
Vou dar uma olhada em um PR para isso. Embora eu não tenha contribuído para os pandas antes, veremos se consigo concluí-lo em tempo hábil.

Encontrou algo nesse sentido quando você muda para trás, então

import pandas_datareader.data as web
import pandas as pd

tickers = ['F','AAPL','NFLX','AMZN','GOOG']

df = pd.DataFrame()
for ticker in tickers:
    data = web.DataReader(ticker, 'iex', '2018-01-01', '2018-06-01')
    data['ticker'] = ticker
    df = df.append(data)

df = df.reset_index()
df['5_day_growth'] = df.groupby('ticker').close.pct_change(periods=-5)
df['5_day_growth_alt'] = df.groupby('ticker').close.pct_change(periods=5).shift(-5)

O método alternativo fornece saída correta em vez de alterar o cálculo.

print(df[['date','ticker','close','5_day_growth', '5_day_growth_alt']].head(6))

          date ticker    close  5_day_growth  5_day_growth_alt
0  2018-01-02      F  12.1939     -0.032115          0.033181
1  2018-01-03      F  12.2903     -0.020717          0.021155
2  2018-01-04      F  12.5022     -0.013672          0.013862
3  2018-01-05      F  12.7141     -0.002268          0.002273
4  2018-01-08      F  12.6659      0.003820         -0.003805
5  2018-01-09      F  12.5985      0.073894         -0.068810

Uma solução alternativa para isso é usar apply . Isso deve produzir o resultado desejado:

df['%_groupby'] = df.groupby('grp')['a'].apply(lambda x: x.pct_change())

Esta página foi útil?
0 / 5 - 0 avaliações