Home > Back-end >  Pandas .mean() method from .pct_change() returns nan value
Pandas .mean() method from .pct_change() returns nan value

Time:05-11

I am currently trying to get the mean of a pandas series representing the percent change of another pandas series that is the percent change of the original series; however, when I try to get the mean by using acc.mean() it returns nan. This is not the case for pct_returns.mean() which returns the mean. Also, both of these series plot correctly (pct_returns, acc) with pyplot so I am unsure why I cannot take the mean correctly.

Here is some sample code as an example:

import yfinance as yf, pandas as pd, numpy as np
from matplotlib import pyplot as plt

tick = yf.Ticker('AAPL')
data = tick.history('5y')

data_prices = data['Close']
pct_returns = data_prices.pct_change()
print(pct_returns.mean())

plt.plot(pct_returns)
plt.show()

acc = pct_returns.pct_change()
print(acc.mean())

plt.plot(acc)
plt.show()

CodePudding user response:

Because there is nothing to compare it against, the first element returned by pct_change is NaN. You need to exclude the first row. Maybe:

print(acc.dropna().mean())

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pct_change.html

CodePudding user response:

Because your acc contains positive and negative infinity, which are impossible to add together:

>>> acc.agg(['min', 'max'])

min   -inf
max    inf
Name: Close, dtype: float64

You get those values when pct_returns is close to 0. Division by 0 returns inf or -inf according to the IEEE 754 Standard:

>>> pct_returns[np.isclose(pct_returns, 0)]

Date
2017-12-22    0.0
2020-07-02    0.0
Name: Close, dtype: float64

To elaborate: mean = sum / count (NaNs are ignored - they neither go to sum nor count). So the issue is with the sum.

# When the sum is NaN, you can't calculate mean
>>> acc.sum()
nan

# Instead of an error, division by 0 result
# in  inf or -inf in numpy and a warning
>>> np.divide(1, 0), np.dvide(-1, 0)
RuntimeWarning: divide by zero encountered in true_divide
  np.divide(1, 0), np.divide(-1, 0)
(inf, -inf)

# Infinity plus or minus anything is still infinity
>>> np.inf   100, -np.inf - 100
(inf, -inf)

# Infinity plus negative infinity result in nan
# They don't cancel each other
>>> np.inf   -np.inf
nan
  • Related