Pandas: BOGUE: groupby.pct_change () ne fonctionne pas correctement dans Pandas 0.23.0. Le regroupement est ignoré.

Créé le 25 mai 2018  ·  4Commentaires  ·  Source: pandas-dev/pandas

Exemple de code

>>>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)

Description du problème

Lorsqu'il y a différents groupes dans un dataframe, en utilisant groupby on s'attend à ce que la fonction pct_change soit appliquée à chaque groupe. Cependant, combiner groupby avec pct_change ne produit pas le résultat correct.

Production:

     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

Production attendue

     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

Sortie de pd.show_versions()

VERSIONS INSTALLÉES


commit: aucun
python: 3.6.3.final.0
bits python: 64
OS: Darwin
Version du système d'exploitation: 17.5.0
machine: x86_64
processeur: i386
byteorder: petit
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: Aucun
xarray: Aucun
IPython: 6.1.0
sphinx: 1.6.3
patsy: 0,4,1
dateutil: 2.6.1
pytz: 2018.3
blosc: Aucun
goulot d'étranglement: 1.2.1
tableaux: 3.4.2
numexpr: 2.6.2
plume: Aucune
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: Aucun
psycopg2: Aucun
jinja2: 2.9.6
s3fs: Aucun
fastparquet: Aucun
pandas_gbq: Aucun
pandas_datareader: Aucun

Bug Groupby

Commentaire le plus utile

Une solution de contournement pour cela consiste à utiliser apply . Cela devrait produire le résultat souhaité:

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

Tous les 4 commentaires

Je peux voir que la fonction pct_change dans groupby.py sur la ligne ~ 3944 ne l'implémente pas correctement. Alors que la méthode qu'il remplace l'implémente correctement pour une trame de données. J'aimerais penser que cela devrait être relativement simple à corriger.
Je vais essayer un PR pour ça. Bien que je n'ai jamais contribué aux pandas auparavant, nous verrons donc si je suis en mesure de le terminer en temps opportun.

J'ai trouvé quelque chose dans ce sens quand tu passes en sens inverse

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)

La méthode alternative vous donne une sortie correcte plutôt que de déplacer le calcul.

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

Une solution de contournement pour cela consiste à utiliser apply . Cela devrait produire le résultat souhaité:

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

Cette page vous a été utile?
0 / 5 - 0 notes