使用np.fft.rfft生成代理时间序列触发TypeError问题咨询
问题背景
我的目标是基于经验观测时间序列生成代理时间序列(Surrogate time-series),要求保留序列自相关性与频域功率分布,仅对相位做随机化处理。
实现该任务的标准步骤为:
- 计算时间序列的傅里叶变换
- 对傅里叶分量的相位进行随机化,保持幅值不变
- 将频域计算结果逆变换回时域,得到代理时间序列
问题复现
编写的测试代码如下,用于生成随机时间序列做复现验证:
import numpy as np TS = np.random.normal(0, 1, 3000) # The time-series FFT = np.fft.rfft # FFT of time-series Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2+1)*1.0j) # Generate random phases FFT = FFT * Random_phases # Randomize the phases in the FFT TS = np.fft.irfft(FFT) # Tranforms the frequency-domain back into the time-domain = Surrogate time-series
运行代码抛出如下错误:
Traceback (most recent call last): File "/Users/...", line 7, in <module> Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2+1)*1.0j) # Generate random phases File "mtrand.pyx", line 1121, in numpy.random.mtrand.RandomState.uniform File "_common.pyx", line 615, in numpy.random._common.cont TypeError: 'float' object cannot be interpreted as an integer
待确认问题
- 初步判断错误原因是第7行代码
Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2+1)*1.0j)中计算得到的长度参数为浮点数而非整数,因此触发类型错误,该判断是否正确? - 如何在不破坏频域相位随机化逻辑的前提下修复该问题?
解答
错误判断验证
你的判断完全正确。Python 3中/是浮点除法运算符,无论运算数是否整除,返回结果都是float类型,而np.random.uniform的size参数要求传入整数类型,因此触发该类型错误。
修复方案
修复需要覆盖三处问题,全程不会破坏相位随机化、保留功率谱与自相关性的核心逻辑:
- 修复长度参数类型问题:将长度计算中的浮点除法
/替换为整数除法//,直接得到整数类型的序列长度,匹配np.random.uniform的参数要求。 - 修正傅里叶变换调用笔误:原代码仅将
np.fft.rfft函数对象赋值给变量,没有传入原始序列TS执行计算,后续和相位数组相乘时会触发类型错误,需要补充参数完成傅里叶变换计算。 - 修正相位取值范围:原代码相位取值范围是0π,没有覆盖02π的全相位区间,会导致逆变换后的时域序列出现虚部残留、对称性异常,无法正确保留原序列的统计特性,需要将相位上限调整为
2*np.pi。
修复后的完整可运行代码:
import numpy as np TS = np.random.normal(0, 1, 3000) # 原始输入时间序列 fft_res = np.fft.rfft(TS) # 对实序列执行快速傅里叶变换 # 生成全范围随机相位,长度用整数除法计算得到整数 random_phases = np.exp(np.random.uniform(0, 2*np.pi, len(TS)//2 + 1) * 1.0j) fft_randomized = fft_res * random_phases # 仅随机化相位,傅里叶分量幅值保持不变 TS_surrogate = np.fft.irfft(fft_randomized) # 逆傅里叶变换得到符合要求的代理时间序列
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

