请求关于python写入excel文件的问题
本帖最后由 incrediblejack 于 2020-6-2 22:26 编辑本例的主要功能:
将时域信号通过快速傅里叶变换FFT,转变为频域信号,并对频域信号提取特征,形成新的数据集。
其中,时域信号是很长的,傅里叶变换在原始时域信号上进行多次分段采样,之后的频域信号也是一段数据,而特征提取之后变成一个点,这样一段时域信号--对应一段频域信号--对应一个特征点,多段时域信号--对应多段频域信号--对应多个特征点。
最终形成一个集成了所有特征点的数据集excel文件。
但是目前有bug
错误为:
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/feature202005/p_61_03.py", line 185, in <module>
ff1 = function_f1(xfp_value) #调用f_1函数输入是加了绝对值的频谱幅值xfp_value
File "C:/Users/Administrator/PycharmProjects/feature202005/p_61_03.py", line 47, in function_f1
sum_mid_f1_v1 = input
IndexError: index 125 is out of bounds for axis 0 with size 125
源代码已附上。
各位大神帮忙看看咯!
谢谢!
另外,怎么添加附件呀?我没找到添加附件的选项,我的框框中只有表情和图片,没有“文件”那个按钮啊,所以我附上个链接吧,里面是数据集。
链接: https://pan.baidu.com/s/1U4gADju6QtH2ZRFDLEb3-g 提取码: fgcu
#这个版本是在p_61_02基础上改的。
#2020061219:16
#时域和频域分别绘图
import numpy as np
import matplotlib.pyplot as plt
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import xlrd
import math
import xlwt
workbook = xlwt.Workbook(encoding='utf-8') #写入数据是用的临时变量
booksheet = workbook.add_sheet('Sheet 1', cell_overwrite_ok=True)
train1 = xlrd.open_workbook('shuangtu_13_14.xlsx')#读取原始数据文件
table1 = train1.sheets() #提第一页sheet
len_train = 1000 #设置取用数据长度(可更改)
# p_a = #中间变量,列表p_a
# for i in range(len_train): #1000次
# p_a = table1.row_values(i) #将第1列的内容,逐行读取,存入p_a列表
#原始数据集装入a
a = #中间变量,列表a
for i in range(len_train): #1000次
a=table1.row_values(i) #将第1列的内容,逐行读取,存入a列表
fft_size = 250#快速傅里叶变换长度
start_i = 1 #设置初始提取位置
#傅里叶变换的方法,封装成函数:
def Fast_Fourier_Trans(x):
sampling_rate = 500 #采样频率
t = np.linspace(0, 1, sampling_rate)# 截取一段时间,截取是任意的,这里截取了0~1秒的一段时间。
xs = x #进行原始数据分割和提取,将用于进行傅里叶变换
xf = 2*np.fft.rfft(xs) / fft_size# 傅里叶变换公式,得到频谱幅值
freqs = np.linspace(0, sampling_rate // 2, fft_size // 2 + 1)#横轴: 表示频率, 从0开始,到采样频率//2,一共显示有包括首尾的fft_size/2+1个数
xfp = np.clip(np.abs(xf), 1e-20, 1e100)#为了避免频谱幅值出现负数,添加的取绝对值的步骤。
t_heng = t # 为了后面显示用
return (freqs, xfp, t_heng, xs, t, xf)#多个返回值。
#特征函数,求f_1 对应公式5-12
def function_f1(input):
sum_mid_f1_v1 = 0
sum_mid_f1_v2 = 0
for i in range(len(freqs_value)):
sum_mid_f1_v1 = input
sum_mid_f1_v2 += sum_mid_f1_v1
f_1 = sum_mid_f1_v2 / len(freqs_value)
# print('平均能量,即f1:')
# print(f_1)
# print(' ')
return f_1
#特征函数,求f_2 对应公式5-13
def function_f2(input):
sum_mid_f2_v1 = 0
sum_mid_f2_v2 = 0
for i in range(len(freqs_value)):
sum_mid_f2_v1 = (input - function_f1(input)) ** 2# 式子5-13分子括号里的
sum_mid_f2_v2 += sum_mid_f2_v1# 式子5-13分子。
f_2 = sum_mid_f2_v2 / (len(freqs_value) - 1)
# print('f2:')
# print(f_2)
# print(' ')
return f_2
#特征函数,求f_3 对应公式5-14
def function_f3(input):
sum_mid_f3_v1 = 0
sum_mid_f3_v2 = 0
for i in range(len(freqs_value)):
sum_mid_f3_v1 = (input - function_f1(input)) ** 3
sum_mid_f3_v2 += sum_mid_f3_v1
f_3 = sum_mid_f3_v2 / (len(freqs_value) * ((function_f2(input)) ** 1.5))
# print('f3:')
# print(f_3)
# print(' ')
return f_3
#特征函数,求f_4 对应公式5-15
def function_f4(input):
sum_mid_f4_v1 = 0
sum_mid_f4_v2 = 0
for i in range(len(freqs_value)):
sum_mid_f4_v1 = (input - function_f1(input)) ** 4
sum_mid_f4_v2 += sum_mid_f4_v1
f_4 = sum_mid_f4_v2 / (len(freqs_value) * ((function_f2(input)) ** 2))
# print('f4:')
# print(f_4)
# print(' ')
return f_4
#特征函数,求f_5 对应公式5-16
def function_f5(input):
sum_mid_f5_v1 = 0
sum_mid_f5_v2 = 0
sum_vid_f5_v3 = 0
sum_mid_f5_v4 = 0
for i in range(len(freqs_value)):
sum_mid_f5_v1 = (freqs_value) * (input)
sum_mid_f5_v2 += sum_mid_f5_v1
sum_mid_f5_v3 = input
sum_mid_f5_v4 += sum_mid_f5_v3
f_5 = sum_mid_f5_v2/ sum_mid_f5_v4
# print('f5:')
# print(f_5)
# print(' ')
return f_5
#特征函数,求f_6 对应公式5-17
def function_f6(input):
sum_mid_f6_v1 = 0# fk^2*X(k)
sum_mid_f6_v2 = 0# ∑fk^2*X(k)
sum_mid_f6_v3 = 0# (∑fk^2*X(k))^0.5
sum_mid_f6_v4 = 0# 分母
for i in range(len(freqs_value)):
sum_mid_f6_v1 = ((freqs_value) ** 2) * (input)
sum_mid_f6_v2 += sum_mid_f6_v1
sum_mid_f6_v3 = (sum_mid_f6_v2) ** 0.5# 这个好像算不出来。
sum_mid_f6_v4 += input
f_6 = sum_mid_f6_v3 / sum_mid_f6_v4
# print('f6:')
# print(f_6)
# print(' ')
return f_6
#特征函数,求f_7 对应公式5-18
def function_f7(input):
sum_mid_f7_v1 = 0# fk^4*X(k)
sum_mid_f7_v2 = 0# ∑fk^4*X(k)
sum_mid_f7_v3 = 0# (∑fk^4*X(k))^0.5
sum_mid_f7_v4 = 0# fk^2*X(k)
sum_mid_f7_v5 = 0# ∑fk^2*X(k)
for i in range(len(freqs_value)):
sum_mid_f7_v1 = ((freqs_value) ** 4) * (input)
sum_mid_f7_v2 += sum_mid_f7_v1
sum_mid_f7_v3 = (sum_mid_f7_v2) ** 0.5
sum_mid_f7_v4 = ((freqs_value) ** 2) * (input)
sum_mid_f7_v5 += sum_mid_f7_v4
f_7 = sum_mid_f7_v3 / sum_mid_f7_v5
# print('f7:')
# print(f_7)
# print(' ')
return f_7
#特征函数,求f_8 对应公式5-19
def function_f8(input):
sum_mid_f8_v1 = 0# fk^2*X(k)
sum_mid_f8_v2 = 0# ∑fk^2*X(k)
sum_mid_f8_v3 = 0# fk^4*X(k)
sum_mid_f8_v4 = 0# ∑fk^4*X(k)
sum_mid_f8_v5 = 0# X(k)
sum_mid_f8_v6 = 0# ∑X(k)
sum_mid_f8_v7 = 0# (∑fk^4*X(k))*(∑X(k))
for i in range(len(freqs_value)):
sum_mid_f8_v1 = ((freqs_value) ** 2) * (input)
sum_mid_f8_v2 += sum_mid_f8_v1
sum_mid_f8_v3 = ((freqs_value) ** 4) * (input)
sum_mid_f8_v4 += sum_mid_f8_v3
sum_mid_f8_v5 = input
sum_mid_f8_v6 += sum_mid_f8_v5
sum_mid_f8_v7 = (sum_mid_f8_v4) * (sum_mid_f8_v6)
f_8 = (sum_mid_f8_v7) ** 0.5
# print('f8:')
# print(f_8)
# print(' ')
return f_8
#主流程
for j in range(len_train // fft_size): #这个变量是为了控制写入数据的行数 j
if j < 2:
for er in range(len_train // fft_size):#这个变量是为了控制运行傅立叶变换Fft函数的次数 er
Fft = Fast_Fourier_Trans(a) #调用快速傅里叶变换函数Fft,输入是提取了len_train长度的原始a列表数据
freqs_value = Fft #Fft返回值,这个是干啥的?
xfp_value = Fft #Fft返回值,返回加了绝对值的频谱幅值
t_heng_value = Fft #Fft返回值,返回当前时域(Fft变换之前的)横坐标值
xs_value = Fft #Fft返回值,返回当前时域(Fft变换之前的)纵坐标值
t_value = Fft #Fft返回值,返回采样间隔么?
xf_value = Fft #Fft返回值,返回未加绝对值的频谱幅值(可能会有负的,所以不用这个)
ff1 = function_f1(xfp_value) #调用f_1函数输入是加了绝对值的频谱幅值xfp_value
print("ff1:")
print(ff1) #测试用
print(' ')
ff2 = function_f2(xfp_value) #调用f_2函数。。。下面道理类同
print("ff2:")
print(ff2)
print(' ')
ff3 = function_f3(xfp_value)
ff4 = function_f4(xfp_value)
ff5 = function_f5(xfp_value)
ff6 = function_f6(xfp_value)
ff7 = function_f7(xfp_value)
ff8 = function_f8(xfp_value)
rowdata = #形成一行数值
print('rowdata:')
print(rowdata) #测试用
print(' ')
for i in range(len(rowdata)): #这个变量i是为了遍历上面的rowdata,为了将来写入excel表格
booksheet.write(j,i, rowdata) #读取rowdata的第i个,写入excel的第j列,第i行
i += 1
er += 1
start_i += fft_size#执行完一轮Fft之后变量start_i增加一个采样周期fft_size之后重新计算
j += 1
else:
break
plt.figure(figsize=(8,8))#生成画布
plt.subplot(211) #生成子图#这个图是
plt.plot(t_heng_value, xs_value)#时域图
plt.xlabel(u'时间(秒)', fontproperties='FangSong')
plt.title(u'原始幅值',fontproperties='FangSong')
plt.subplot(212)
plt.plot(freqs_value, xfp_value)##频域图
plt.xlabel(u'频率(HZ)', fontproperties='FangSong')
plt.ylabel(u'幅值',fontproperties='FangSong')
plt.subplots_adjust(hspace=0.4)
plt.show()
# print('xfp_value')
# print(xfp_value)
# print(' ')
# print('xfp_value 傅立叶变换后的点纵坐标的个数:')
# print(len(xfp_value))
# print(' ')
# print('xs_value 傅里叶变换后的点横坐标的个数:')
# print(len(xs_value))
# print(' ')
workbook.save('p_61_02.xls') #保存
IndexError: index 125 is out of bounds for axis 0 with size 125应该是你的 excel 文件数据有问题,看下125行是不是空行? 将时域信号通过快速傅里叶变换FFT,转变为频域信号,并对频域信号提取特征,形成新的数据集。
我记得Origin有直接FFT的选项,你可以试试这个,看看原始数据有没有问题 Twilight6 发表于 2020-6-3 07:32
应该是你的 excel 文件数据有问题,看下125行是不是空行?
我看了,原始数据没有空行。我如果更改sampling_rate、fft_size等参数,这个报错的125还会变成其他数值的。 jijidebaba 发表于 2020-6-3 07:58
我记得Origin有直接FFT的选项,你可以试试这个,看看原始数据有没有问题
谢谢,回头我可以试试,但是这个基于numpy的FFT的组装成新表格的例子,我没有搞定的话实在是迈不过去这个坎儿啊 incrediblejack 发表于 2020-6-3 09:03
我看了,原始数据没有空行。我如果更改sampling_rate、fft_size等参数,这个报错的125还会变成其他数值的 ...
好吧 上传附件是有权限的,不同账号等级,功能不能。
努力回帖,发帖升级吧。
到达鱼油1,就可以发截图了。 一直没有人回复给我正确的答案,我写了个简单版的,以排除傅里叶变换对结果可能带来的影响,见帖子:https://fishc.com.cn/forum.php?mod=viewthread&tid=171185&page=1#pid4738298
感谢在这个帖子中 @yifenyu 提供的修改思路。
我在那个帖子的答案的基础上,把傅里叶变换内容加进去了,经过运行结果正确。鉴于目前没人提供答案,那我就自己把改过的代码粘上来咯。只能发自己最佳答案了嘿嘿,各位见谅~
改后的代码:
#本例在20200603的基础上,加上了傅里叶变换的内容,也就是频域特征提取,然后看能否实现提取后形成一个新的表格功能。
#20200605写的
import numpy as np
import matplotlib.pyplot as plt
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import xlrd
import xlwt
import typing
workbook = xlwt.Workbook(encoding='utf-8')
booksheet = workbook.add_sheet('Sheet 1', cell_overwrite_ok=True)
train1 = xlrd.open_workbook('shuangtu_13_14.xlsx')#读取原始数据文件
table1 = train1.sheets() #提第一页sheet
len_train = 20003 #设置取用数据长度(可更改)
a = #中间变量,列表a
for i in range(len_train): #1000次
a=table1.row_values(i) #将第1列的内容,逐行读取,存入a列表
#全局变量
changdu = 250
start_i = 1
def calculateMean(x, start_i): #注意,这里我原来写的是这样,def calculateMean(x),别人帮我改了。就是这个新逻辑。
xf = []
xs = x
for p in xs:
xf.append(p*p*3) #注意这里不要写成 xf = xf.apppend(p*3)
return (x, xs, xf)
#傅立叶变换函数
def Fast_Fourier_Trans(x, start_i):
sampling_rate = 500 #采样频率
t = np.linspace(0,1,sampling_rate) #截取一段时间,这个有待研究
xs = x
xf = 2*np.fft.rfft(xs) / changdu #傅立叶变换计算公式,得到频谱幅值
freqs = np.linspace(0, sampling_rate // 2, changdu//2 + 1) #这个干啥用的?回头自己在图中改改试试
xft = np.clip(np.abs(xf), 1e-10, 1e100) #频谱幅值加了绝对值之后的。为了避免出现负数。
t_heng = t #不知道用上用不上。随后再更改。
return (t, xs, xf, freqs, xft, t_heng) #:t:xs:xf:freqs:xftt_heng
#f1
def func_f1(input):
sum_mid_f1_v1 = 0# 当前值
sum_mid_f1_v2 = 0# 加和值
for i in range(len(res_freqs)):
sum_mid_f1_v1 = input
sum_mid_f1_v2 += sum_mid_f1_v1
f_1 = sum_mid_f1_v2 / len(res_freqs)
return f_1
#f2
def func_f2(input):
sum_mid_f2_v1 = 0
sum_mid_f2_v2 = 0
for i in range(len(res_freqs)):
sum_mid_f2_v1 = (input - func_f1(input)) ** 2# 式子5-13分子括号里的 #注意这里func_f1不能去掉(input)
sum_mid_f2_v2 += sum_mid_f2_v1# 式子5-13分子。
f_2 = sum_mid_f2_v2 / (len(res_freqs) - 1)
return f_2
#f3
def func_f3(input):
sum_mid_f3_v1 = 0
sum_mid_f3_v2 = 0
for i in range(len(res_freqs)):
sum_mid_f3_v1 = (input - func_f1(input)) ** 3 #注意这里先不去掉(input)试试,后同。
sum_mid_f3_v2 += sum_mid_f3_v1
f_3 = sum_mid_f3_v2 / (len(res_freqs) * ((func_f2(input)) ** 1.5))
return f_3
#f4
def func_f4(input):
sum_mid_f4_v1 = 0
sum_mid_f4_v2 = 0
for i in range(len(res_freqs)):
sum_mid_f4_v1 = (input - func_f1(input)) ** 4
sum_mid_f4_v2 += sum_mid_f4_v1
f_4 = sum_mid_f4_v2 / (len(res_freqs) * ((func_f2(input)) ** 2))
return f_4
#f5
def func_f5(input):
sum_mid_f5_v1 = 0
sum_mid_f5_v2 = 0
sum_vid_f5_v3 = 0
sum_mid_f5_v4 = 0
for i in range(len(res_freqs)):
sum_mid_f5_v1 = (res_freqs) * (input) #这个公式对么?对照公式看一看。后面也检查下
sum_mid_f5_v2 += sum_mid_f5_v1
sum_mid_f5_v3 = input
sum_mid_f5_v4 += sum_mid_f5_v3
f_5 = sum_mid_f5_v2/ sum_mid_f5_v4
return f_5
#f6:
def func_f6(input):
sum_mid_f6_v1 = 0# fk^2*X(k)
sum_mid_f6_v2 = 0# ∑fk^2*X(k)
sum_mid_f6_v3 = 0# (∑fk^2*X(k))^0.5
sum_mid_f6_v4 = 0# 分母
for i in range(len(res_freqs)):
sum_mid_f6_v1 = ((res_freqs) ** 2) * (input)
sum_mid_f6_v2 += sum_mid_f6_v1
sum_mid_f6_v3 = (sum_mid_f6_v2) ** 0.5# 这个好像算不出来。
sum_mid_f6_v4 += input
f_6 = sum_mid_f6_v3 / sum_mid_f6_v4
return f_6
#f7:
def func_f7(input):
sum_mid_f7_v1 = 0# fk^4*X(k)
sum_mid_f7_v2 = 0# ∑fk^4*X(k)
sum_mid_f7_v3 = 0# (∑fk^4*X(k))^0.5
sum_mid_f7_v4 = 0# fk^2*X(k)
sum_mid_f7_v5 = 0# ∑fk^2*X(k)
for i in range(len(res_freqs)):
sum_mid_f7_v1 = ((res_freqs) ** 4) * (input)
sum_mid_f7_v2 += sum_mid_f7_v1
sum_mid_f7_v3 = (sum_mid_f7_v2) ** 0.5
sum_mid_f7_v4 = ((res_freqs) ** 2) * (input)
sum_mid_f7_v5 += sum_mid_f7_v4
f_7 = sum_mid_f7_v3 / sum_mid_f7_v5
return f_7
#f8:
def func_f8(input):
sum_mid_f8_v1 = 0# fk^2*X(k)
sum_mid_f8_v2 = 0# ∑fk^2*X(k)
sum_mid_f8_v3 = 0# fk^4*X(k)
sum_mid_f8_v4 = 0# ∑fk^4*X(k)
sum_mid_f8_v5 = 0# X(k)
sum_mid_f8_v6 = 0# ∑X(k)
sum_mid_f8_v7 = 0# (∑fk^4*X(k))*(∑X(k))
for i in range(len(res_freqs)):
sum_mid_f8_v1 = ((res_freqs) ** 2) * (input)
sum_mid_f8_v2 += sum_mid_f8_v1
sum_mid_f8_v3 = ((res_freqs) ** 4) * (input)
sum_mid_f8_v4 += sum_mid_f8_v3
sum_mid_f8_v5 = input
sum_mid_f8_v6 += sum_mid_f8_v5
sum_mid_f8_v7 = (sum_mid_f8_v4) * (sum_mid_f8_v6)
f_8 = (sum_mid_f8_v7) ** 0.5
return f_8
for j in range(len_train // changdu):
fun_FFT = Fast_Fourier_Trans(a, j*changdu)
res_t = fun_FFT
res_xs = fun_FFT
res_xf = fun_FFT
res_freqs = fun_FFT
res_xft = fun_FFT
res_t_heng = fun_FFT
ff1 = func_f1(res_xft)
ff2 = func_f2(res_xft)
ff3 = func_f3(res_xft)
ff4 = func_f4(res_xft)
ff5 = func_f5(res_xft)
ff6 = func_f6(res_xft)
ff7 = func_f7(res_xft)
ff8 = func_f8(res_xft)
rowdata =
for i in range(len(rowdata)):
booksheet.write(j, i, rowdata)
workbook.save('20200605_fourier.xls')
#这个例子可以实现喔。
incrediblejack 发表于 2020-6-5 15:22
一直没有人回复给我正确的答案,我写了个简单版的,以排除傅里叶变换对结果可能带来的影响,见帖子:https: ...
诶?自己没法给自己设置最佳答案诶{:5_94:} 向楼主学习,以后批量处理时域场的数据说不定可以用到{:10_254:} jijidebaba 发表于 2020-6-6 16:08
向楼主学习,以后批量处理时域场的数据说不定可以用到
过奖过奖,是我应该多虚心学习{:5_109:}
页:
[1]