python基础知识
x = np.linspace(0.05, 10, 1000) # 在0.05到10的区间中,等差选取1000个,端点不属于。返回一个数组
格式: array = numpy.linspace(start, end, num=num_points)
将在start
和end
之间生成一个统一的序列,共有num_points
个元素。
# int() 函数用于将一个字符串或数字转换为整型。class int(x, base=10)x -- 字符串或数字。 base -- 进制数,默认十进制。
# np.pi表示π np.sin() 正弦值
# 功能: np.array 和np.asarray 将数据转化为矩阵
# math.factorial(x) 方法返回 x 的阶乘。
# 2.2204e-16表示2.2204乘以10的负16次方,即2.2204×10^-16
# 2.29988467e+01= 22.9988467
# exp就是e print(math.exp(1))
# np.argsort(i))对X每一行进行由小到大排序,并返回排序后的索引,并将索引转化为字符串
# Counter(list1) 快速的计数,将元素数量统计,然后计数并返回一个字典,键为元素,值为元素个数。
# 集合(Set)是无序和无索引的集合。在 Python 中,集合用花括号编写。
# 字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括号编写,拥有键和值。
# mp = {} 这就是字典 mp[k] 相当于取 字典中 key为 k 的value 遍历key mp.keys() 遍历value mp.values()
# 元组是有序且不可更改的集合。在 Python 中,元组是用圆括号编写的。
# a2 = [1,2,3,4,5,6] print(a2[2:]); [3, 4, 5, 6] [start:end] [2:4] [3, 4] [-1]默认最后一个
# x[:,n]表示在全部数组(维)中取第n个数据,直观来说,x[:,n]就是取所有集合的第n个数据, https://blog.csdn.net/u014159143/article/details/80307717
# 将某一类型的变量或者常量转换为字符串对象,可以使用str()
还有 python的 for 循环,跟他在同一列的就算他for循环内的
举个例子
for i in range(1,3):
print("i"+str(i))
for j in range(1,3):
print("j"+str(j),end="")
print("\n")
print("ix")
输出
i1
j1j2
ix
i2
j1j2
ix
排列熵算法
参考以上文章。但是我发现都没有 t=2的例子, 并且网上有很多例子居然是错的,真是害人时间啊。 下面我写一下自己的理解和举例子。
m:嵌入维数 其实就是一个序列中取多少个
t:延时时间 相当于步长
k为重构分量,k=n-(m-1)*t 算出这个矩阵总共有多少行
假如这个序列 是[ 1,2,3,4,5,6]
假如m=3 ,t=1
那么他就会变成
[
[1,2,3],
[2,3,4],
[3,4,5],
[4,5,6]
]
那么 k = 6- (3-1)*1 =4,也就是有四行
假如我要找第一行([1,2,3])的那个元素3 ,那么就是 X(1+(3-1)*t)= X3 (注意3是下标。)
重点难点来了
假如这个序列 还是[ 1,2,3,4,5,6] m=3 ,t=2
那么他就会变成
[
[1,3,5],
[2,4,6]
]
那么 k = 6- (3-1)*2 =2,也就是有两行
假如我要找第一行([1,3,5])的那个元素5 ,那么就是 X(1+(3-1)*t)= X5 (注意5是下标。)
所以现在看的懂这个图了吧
AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘的解决办法
是在使用python的matplotlib库的时候发现无法绘制出图
我们看下面的题目。
从脑电信号中提取排列熵特征:a)设计排列熵算法;b)从64通道的脑电数据中提取排列熵特征;实验提供的脑电数据采样率为128Hz,时长为6分钟,测试数据选择前10秒数据,即每通道脑电数据的前1280个采样点。
64通道, 每通道脑电数据的前1280个采样点。
相当于定义一个二维数组。
data[1280][64]
可以理解为, data[i] 是行数据 data[i] [j] 为列数据(也就是特征,也就是你的参数)
一维是行,二维是列。
import math
import numpy as np
import scipy.io as scio
import pandas as pd
from collections import Counter
from operator import itemgetter
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt;
# 获取排列
def getC(arr, arr_s, m):
res = np.zeros(m)
Xmp = {}
for j in range(0, len(arr)):
Xmp[str(arr[j])] = j
for j in range(0, len(arr)):
res[j] = Xmp[str(arr_s[j])]
return res
# 统计频率
def getF(Xs):
mp = {}
p = []
for arr in Xs:
k = str(arr)
if k in mp.keys():
mp[k] += 1
else:
mp[k] = 1
for i in mp.values():
p.append(i / len(Xs))
return p
# 排列熵计算
def permutationEntropy(x, m, l):
# 空间重构
n = len(x)
Xs = []
for i in range(0, n - m + l):
X = x[i:i + m * l:l]
Xsd = sorted(X)
# Xs.append(getC(X, Xsd, m))
Xs.append(np.argsort(X))
# 频率
p = getF(Xs)
# 排列熵
h = 0
for i in range(len(p)):
h += p[i] * math.log(p[i])
# 归一化
return -h / math.log(math.factorial(m))
# 绘图
def draw(eps1, eps2, eps3, eps4):
# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置字符集支持中文
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(32, 12))
labels = []
for i in range(0, 64):
labels.append(i)
# 设置x名字和字体大小
plt.xlabel("通道", fontsize=14)
# 设置y名字和字体大小
plt.ylabel("排列熵", fontsize=14)
# plt.plot 画图
plt.plot(labels, eps1, c='r', label="ep_m4_l1")
plt.plot(labels, eps2, c='b', label="ep_m4_l2")
plt.plot(labels, eps3, c='g', label="ep_m8_l1")
plt.plot(labels, eps4, c='y', label="ep_m8_l2")
plt.tick_params(axis='both', labelsize=14)
plt.legend()
plt.show()
def main():
t = 1
count=0;
data = scio.loadmat('EEG64CHs.mat');
data1 = data.get('EEG64CHs');
eps_m4_l1 = []
eps_m4_l2 = []
eps_m8_l1 = []
eps_m8_l2 = []
for i in range(0, 64):
datas = []
for j in range(0, 1280):
# 遍历64次下面的代码, 因为有64个通道 。
datas.append(data1[j][i])
es = permutationEntropy(datas, 4, 1)
eps_m4_l1.append(es)
print(es)
print(count)
count+=1
es = permutationEntropy(datas, 4, 2)
eps_m4_l2.append(es)
es = permutationEntropy(datas, 8, 1)
eps_m8_l1.append(es)
es = permutationEntropy(datas, 8, 2)
eps_m8_l2.append(es)
draw(eps_m4_l1, eps_m4_l2, eps_m8_l1, eps_m8_l2)
if __name__ == "__main__":
main()
python双冒号用法
# 该::分开结束,开始,步长值。 原本是要这样的 x[i:i + m * l-l:l] ,但是因为取数是左闭右开,所以不用-l
X = x[i:i + m * l:l]
plot画图
其中主要用到的。
plt.rcParams['font.family'] = 'serif' # 设置全局字体类型
plt.rcParams['font.weight'] = 'bold' # 设置全局字体粗细
# 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字符集支持中文 plt.rcParams['axes.unicode_minus'] = False
看这篇文章,很棒
Python可视化——matplotlib.pyplot绘图的基本参数详解
关于这代码,对应的图片就是这样
plt.plot(x, y, c,ls, lw, label, alpha, **kwargs)
def draw(eps1, eps2, eps3, eps4):
# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置字符集支持中文
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(12, 12))
labels = []
for i in range(0, 64):
labels.append(i)
# 设置x名字和字体大小
plt.xlabel("通道", fontsize=14)
# 设置y名字和字体大小
plt.ylabel("排列熵", fontsize=14)
# plt.plot 画图 x ,y plt.plot(x, y, c,ls, lw, label, alpha, **kwargs)
plt.plot(labels, eps1, c='r', label="ep_m4_l1")
plt.plot(labels, eps2, c='b', label="ep_m4_l2")
plt.plot(labels, eps3, c='g', label="ep_m8_l1")
plt.plot(labels, eps4, c='y', label="ep_m8_l2")
plt.tick_params(axis='both', labelsize=14)
plt.legend()
plt.show()