>>>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)
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
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
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
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.
peut-être lié à https://github.com/pandas-dev/pandas/issues/11811
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())
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())