Voici mon cadre de données Pandas:
prices = pandas.DataFrame([1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95,
1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42,
1036.24, 1015.00, 1015.20])
Voici ma fonction daily_return
:
def daily_return(prices):
return prices[:-1] / prices[1:] - 1
Voici la sortie qui provient de cette fonction:
0 NaN
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 NaN
Pourquoi ai-je cette sortie?
Les opérations effectuant l'alignement sur l'index, vous pouvez convertir l'un des DataFrames en tableau:
prices[:-1].values / prices[1:] - 1
ou
prices[:-1] / prices[1:].values - 1
dépend de ce que l'index du résultat que vous voulez.
ou utilisez la méthode shift()
:
prices.shift(1) / prices - 1
et:
prices / prices.shift(1) - 1
Pourquoi ne pas utiliser la méthode très pratiquepct_change
fournie par pandas
par défaut:
import pandas as pd
prices = pandas.DataFrame([1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95,
1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42,
1036.24, 1015.00, 1015.20])
daily_return = prices.pct_change(1) # 1 for ONE DAY lookback
monthly_return = prices.pct_change(21) # 21 for ONE MONTH lookback
annual_return = prices.pct_change(252) # 252 for ONE YEAR lookback
Original prices
:
print(prices)
0
0 1035.23
1 1032.47
2 1011.78
3 1010.59
4 1016.03
5 1007.95
6 1022.75
7 1021.52
8 1026.11
9 1027.04
10 1030.58
11 1030.42
12 1036.24
13 1015.00
14 1015.20
Retour quotidien asprices.pct_change(1)
:
print(prices.pct_change(1))
0
0 NaN
1 -0.002666
2 -0.020039
3 -0.001176
4 0.005383
5 -0.007953
6 0.014683
7 -0.001203
8 0.004493
9 0.000906
10 0.003447
11 -0.000155
12 0.005648
13 -0.020497
14 0.000197
Juste un complément à la réponse de @YaOzl, et au cas où quelqu'un lirait ceci. Si vos données de retour sont une feuille de calcul avec plusieurs stocks:
>>> prices = pandas.DataFrame(
{"StkCode":["StockA","StockA","StockA","StockA","StockA","StockB","StockB","StockB","StockB","StockB","StockC","StockC","StockC","StockC","StockC",],
"Price":[1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95, 1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42, 1036.24, 1015.00, 1015.20]}
)
Ce qui vous donne:
Price StkCode
0 1035.23 StockA
1 1032.47 StockA
2 1011.78 StockA
3 1010.59 StockA
4 1016.03 StockA
5 1007.95 StockB
6 1022.75 StockB
7 1021.52 StockB
8 1026.11 StockB
9 1027.04 StockB
10 1030.58 StockC
11 1030.42 StockC
12 1036.24 StockC
13 1015.00 StockC
14 1015.20 StockC
Ensuite, vous pouvez simplement utiliser conjointement .pct_change (k) avec .groupby (StkCode) . Et c’est trois fois plus rapide que d’utiliser un itérateur ... (j’ai essayé avec mon jeu de données, de réduire avec succès le temps de traitement de 10 heures à 20 secondes !! )
>>> prices["Return"] = prices.groupby("StkCode")["Price"].pct_change(1)
Vous donne:
Price StkCode Return
0 1035.23 StockA NaN
1 1032.47 StockA -0.002666
2 1011.78 StockA -0.020039
3 1010.59 StockA -0.001176
4 1016.03 StockA 0.005383
5 1007.95 StockB NaN
6 1022.75 StockB 0.014683
7 1021.52 StockB -0.001203
8 1026.11 StockB 0.004493
9 1027.04 StockB 0.000906
10 1030.58 StockC NaN
11 1030.42 StockC -0.000155
12 1036.24 StockC 0.005648
13 1015.00 StockC -0.020497
14 1015.20 StockC 0.000197