在之前的一篇博客 —— ​​将一维时间序列转化成二维图片​​中,我翻译了一篇文章,说的是将一个时间序列信号转换成二维图片:

Python:使用 pyts 把一维时间序列转换成二维图片_机器视觉

然后在文章的最后发了一个 ​​Github​​ 代码,这个代码是原文作者的代码,有人反应代码不能跑起来。

这里我使用 Python 的一个第三方库 pyts,参考官方文档,改写了一下。测试了一下,可以在 Pyhon3.7 上成功运行。官方上说明的是 Python 版本应该不小于 3.5,代码已经上传至 ​​GitHub​​.

1/ 安装 pyts 库

注: 以前有一个版本的代码使用的 pyts 库的版本为 0.7.1,目前最新版本的 pyts 库改变比较大,会出现 ​​cannot import name 'GASF' from 'pyts.image'​​ 的报错。该问题已经在最新 GitHub 上的版本重新写了最新版本 pyts 的代码,如果想要使用旧版本的代码,安装的时候要指定 pyts 的版本,然后使用本文中旧版本的那个代码。


安装特定版本的 Python 包的方法,打开命令行,使用 pip 命令安装:​​pip install pyts==0.7.1​


2/ 准备一维时间序列

我使用 MATLAB 生成了一个 sin x 的时间序列图,plot 出来是这样的:

Python:使用 pyts 把一维时间序列转换成二维图片_github_02

总共有 512 个点,也就是最大能够生成 512 × 512 512\times 512 512×512 的图片。

要把生成的图片保存为 .csv 文件:

Python:使用 pyts 把一维时间序列转换成二维图片_新版本_03

3/ 转换成图片

接下来就是简单地转换成二维图片了,先贴代码吧,或者可以在我的 ​​GitHub​​ 上下载,里面有批量处理和保存 GAF 图片的代码:

使用新版本的 pyts,版本如下,这也是目前 GitHub 里面版本的代码:

import numpy as np
import matplotlib.pyplot as plt
from pyts.image import GramianAngularField

sin_data = np.loadtxt('sinx.csv', delimiter=",", skiprows=0).reshape(1, -1)
image_size = 28

gasf = GramianAngularField(image_size=image_size, method='summation')
sin_gasf = gasf.fit_transform(sin_data)
gadf = GramianAngularField(image_size=image_size, method='difference')
sin_gadf = gadf.fit_transform(sin_data)
images = [sin_gasf[0], sin_gadf[0]]
titles = ['Summation', 'Difference']

fig, axs = plt.subplots(1, 2, constrained_layout=True)
for image, title, ax in zip(images, titles, axs):
ax.imshow(image)
ax.set_title(title)
fig.suptitle('GramianAngularField', y=0.94, fontsize=16)
plt.margins(0, 0)
plt.savefig("GramianAngularField.pdf", pad_inches=0)
plt.show()

如果是使用 0.7.1 之前版本的,可以使用下面的代码:

import numpy as np
import matplotlib.pyplot as plt
from pyts.image import GASF, GADF

x = np.loadtxt(open("sinx.csv","rb"),delimiter=",",skiprows=0).T
# print(type(x),x.shape)

X = x[0:]
X = X.reshape(1, -1)
print(type(X),X.shape)
image_size = 28
gasf = GASF(image_size)
X_gasf = gasf.fit_transform(X)
print(X_gasf.shape)
print(X_gasf[0,4,2],X_gasf[0,2,4])
gadf = GADF(image_size)
X_gadf = gadf.fit_transform(X)
print(X_gadf[0,1,2],X_gadf[0,2,1])

# Show the results for the first time series
plt.figure(figsize=(16, 8))
plt.subplot(121)
plt.imshow(X_gasf[0], cmap='rainbow', origin='lower')
plt.title("GASF", fontsize=16)
plt.subplot(122)
plt.imshow(X_gadf[0], cmap='rainbow', origin='lower')
plt.title("GADF", fontsize=16)
plt.savefig('sinx.jpg')
plt.show()

运行,出来的效果是这样的:

Python:使用 pyts 把一维时间序列转换成二维图片_新版本_04

文中的 .csv 文件和代码都放在我的仓库中,如果对你有帮助,可以在 ​​GitHub​​ 中给我个 Star,这会是对我的一份鼓励与肯定!