我试图计算熊猫系列的熵。具体地说,我将Direction
中的字符串分组为一个序列。具体而言,使用此功能:
diff_dir = df.iloc[0:,1].ne(df.iloc[0:,1].shift()).cumsum()
将返回Direction
中在更改之前相同的字符串计数。所以对于相同Direction
字符串的每个序列,我想计算X,Y
的熵
使用代码,相同字符串的顺序为:
0 1
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 3
9 3
此代码以前可以工作,但现在返回错误。我不确定这是否是升级后发生的
import pandas as pd
import numpy as np
def ApEn(U, m = 2, r = 0.2):
'''
Approximate Entropy
Quantify the amount of regularity over time-series data.
Input parameters:
U = Time series
m = Length of compared run of data (subseries length)
r = Filtering level (tolerance). A positive number
'''
def _maxdist(x_i, x_j):
return max([abs(ua - va) for ua, va in zip(x_i, x_j)])
def _phi(m):
x = [U.tolist()[i:i + m] for i in range(N - m + 1)]
C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
return (N - m + 1.0)**(-1) * sum(np.log(C))
N = len(U)
return abs(_phi(m + 1) - _phi(m))
def Entropy(df):
'''
Calculate entropy for individual direction
'''
df = df[['Time','Direction','X','Y']]
diff_dir = df.iloc[0:,1].ne(df.iloc[0:,1].shift()).cumsum()
# Calculate ApEn grouped by direction.
df['ApEn_X'] = df.groupby(diff_dir)['X'].transform(ApEn)
df['ApEn_Y'] = df.groupby(diff_dir)['Y'].transform(ApEn)
return df
df = pd.DataFrame(np.random.randint(0,50, size = (10, 2)), columns=list('XY'))
df['Time'] = range(1, len(df) + 1)
direction = ['Left','Left','Left','Left','Left','Right','Right','Right','Left','Left']
df['Direction'] = direction
# Calculate defensive regularity
entropy = Entropy(df)
错误:
return (N - m + 1.0)**(-1) * sum(np.log(C))
ZeroDivisionError: 0.0 cannot be raised to a negative power
似乎在调用
ApEn._phi()
函数时,N
和m
的特定值可能最终返回一个0
。然后需要将其提升到-1的负幂,但这是未定义的(另请参见Why does zero raised to the power of negative one equal infinity?)为了举例说明,我尝试专门复制您的场景,在
transform
操作的第一次迭代中,会发生以下情况:(第一个groupby有2个元素)
因此,当您得到
_phi()
的返回值时,实际上是在执行(N - m + 1.0)**-1 = (2 - 3 + 1)**-1 = 0**-1
,这是未定义的。也许这里的关键是,你说你是按单个方向分组的,并将U
数组传递到近似熵函数中,但是你是按diff_X
和diff_Y
分组的,由于所应用方法的性质,这会导致非常小的分组。据我所知,如果你想计算每个方向的近似熵,你只需要按“方向”分组:这将产生如下数据帧:
问题是因为以下代码
考虑当{{CD1>}和^ ^}时发生的情况,当A组由GROMPBY产生时,其大小将为1。由于
m==2
这最终成为我们{}是未定义的,错误也是未定义的
现在如果我们从理论上看,你如何定义只有一个值的时间序列的近似熵;高度不可预测,因此应尽可能高。对于这种情况,让我们将其设置为
np.nan
,表示它未定义(熵总是大于等于0)代码
输出:
较大样本(导致0**-1问题)
输出:
你必须处理你的零分割。也许这样:
然后,您将在groupbys上遇到长度不匹配,df和diff_X必须具有相同的长度
相关问题 更多 >
编程相关推荐