更新以反映评论
我需要将MATLAB代码移植到python中。不幸的是,尽管在调试和谷歌搜索上经历了许多不眠之夜,但是我却无法运行我的代码。这是有问题的MATLAB代码:
clc;
serie =0:50;
serie = serie - mean(serie);
y = cumsum(serie);
L = length(y);
%Calculate the detrended fluctuation short term coefficient
npuntos = 10;
f1=zeros(1,npuntos);
for n1=4:16
%Segmentation
seg =(1:n1:L);
%disp(length(seg))
yn = zeros(1,L);
for k = 1:length(seg)-1
yaux = y(seg(k):seg(k+1)-1);
x = 1:length(yaux);
A=[sum(x.^2),sum(x); sum(x),length(x)];
C=[sum(x.*yaux);sum(yaux)];
v=inv(A)*C;
a=v(1); b=v(2);
pen=a;
ord=b;
ytrend = pen*x + ord;
yn(seg(k):seg(k+1)-1) = ytrend';
end
f1(n1) = sqrt((1/seg(end)).*sum((y(1:seg(end)-1)-yn(1:seg(end)-1)).^2));
end
n1=4:16;
f1=f1(4:end);
p1 = polyfit(log10(n1(1:end-2)),log10(f1(1:end-2)),1);
alpha1 = p1(1);
disp(alpha1)
我将代码翻译成python的尝试如下:
import numpy as np
data = np.arange(start=0, stop=51, step=1)
data = data.transpose()
data = data - np.mean(data)
y = np.cumsum(data)
L = len(y)
# Estimate the value of alpha1
npuntos = 12
f1 = [0] * npuntos
for i, n1 in enumerate(np.arange(start=4, stop=16, step=1)):
seg = np.arange(start=0, stop=L, step=n1) # Potential error
yn = [0] * L
for k in np.arange(start=0, stop=len(seg)-1, step=1): # Potential Error
yaux = y[seg[k]:seg[k + 1]-1] # Potential Error
x = np.arange(start=1, stop=len(yaux) + 1, step=1)
A = [[sum(x ** 2), sum(x)], [sum(x), len(x)]]
C = [[sum(x * yaux)], [sum(yaux)]]
v = (np.linalg.inv(A)).dot(C)
pen = v[0]
ord = v[1]
ytrend = pen * x + ord
yn[seg[k]: seg[k + 1] - 1] = ytrend
f1[i] = np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2))
n1 =np.arange(start=4, stop=16, step=1)
f1 = f1[4:]
xx =np.log10(n1[1: - 2])
yy=np.log10(f1[1: - 2])
print(len(xx))
print(len(yy))
p1 = np.polyfit(xx, yy, 1)
alpha1 = p1[1]
print(alpha1)
不幸的是,程序执行此行时出现TypeError
p1 = np.polyfit(xx, yy, 1)
确实可以预期,因为xx的长度为9而xx的长度仅为5。通过使用注释中建议的try / catch块,
try:
f1[n1] = np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2))
except IndexError:
f1.append(np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2)))
错误是由输出修正的,完全是错误的。
我已经通过调试器,但是我不能完全确定该错误。有人可以帮忙吗?PS-如果有人感兴趣,以上代码段应用于计算去趋势波动分析(DFA)。
解决方案
那是因为您有,npuntos = 10所以f1 = [0] * npuntos使您f1 list的大小相等10。然后你遍历
for n1 in np.arange(start=4, stop=16, step=1):
并f1[n1]从10到15访问其中一个IndexError
更新
首先,np.zeros((5,), dtype=np.int)因为您已经在使用np模块,所以可以使用。
其次要弄清楚事情IndexError。我个人不想陷入您要解决的数学问题,因此解决方案不是最好的。只是稍有变化。我相信您知道Python索引是从零开始的。从那开始,您将在第5个元素中开始填充。我不确定您是否想要它。您可以enumerate(np.arange(start=4, stop=16, step=1))为列表创建从零开始的索引:
for i, n1 in enumerate(np.arange(start=4, stop=16, step=1)):
...
f1[i] = np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2))
但是,len(np.arange(start=4, stop=16, step=1))是12不是你创建的大小f1(10)。因此,从这一点出发,您可以创建12元素列表。
npuntos = 12
f1 = [0] * npuntos # or np.zeros((5,), dtype=np.int)
或者,如果需要,也可以append像在MATLAB中一样处理值(如@nekomatic所述)。
所以你需要包装
f1[n1] = np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2))
在try / except:
try:
f1[n1] = np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2))
except IndexError:
f1.append(np.sqrt((1 / seg[-1]) * sum((y[1:seg[-1] - 1] - yn[1:seg[-1] - 1]) ** 2)))