
Redundancy is a empirically tractable measure of the complexity that arises in realworld timeseries data “which results from the dimension, nonlinearity, and nonstationarity of the generating process, as well as from measurement issues such as noise, aggregation, and finite data length”
def permutation_entropy(time_series, m, delay):
Args:
time_series: Time series for analysis
m: Order of permutation entropy
delay: Time delay
Returns:
Vector containing Permutation Entropy
n = len(time_series)
permutations = np.array(list(itertools.permutations(range(m))))
c = [0] * len(permutations)
for i in range(n  delay * (m  1)):
# sorted_time_series = np.sort(time_series[i:i+delay*m:delay], kind='quicksort')
sorted_index_array = np.array(np.argsort(time_series[i:i + delay * m:delay], kind='quicksort'))
for j in range(len(permutations)):
if abs(permutations[j]  sorted_index_array).any() == 0:
c[j] += 1
c = [element for element in c if element != 0]
p = np.divide(np.array(c), float(sum(c)))
pe = sum(p * np.log(p))
return pe