# -*- encoding:utf-8 -*-

import numpy as np

# 1.创建矩阵，使用ndarray对象，只需要将一个list作为参数即可
# 创建X维的ndarray对象, 并获取矩阵行列数
dim_one = np.array([[1, 2, 3, 4, 5]])
print("一维矩阵：\n", dim_one)
print("shape：", dim_one.shape)
print("行数：", dim_one.shape[0])
print("列数：", dim_one.shape[1])

dim_two = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print("二维矩阵：\n", dim_two)
print("shape ：", dim_two.shape)
print("行数：", dim_two.shape[0])
print("列数：", dim_two.shape[1])

# 2.矩阵截取
# 按行列截取，与list相同，通过[]方括号来截取，逗号之前为行，默认第一行
print("截取二维矩阵第一行：", dim_two[0:1])
print("截取二维矩阵第二行，第三、四列：", dim_two[1,2:4])
print("截取二维矩阵第二行：", dim_two[1,:])

# 按条件截取，在[]方括号中传入自身的布尔语句
array_cut = dim_two[dim_two % 2 == 0]
print("截取二维矩阵的偶数：", array_cut)

print("二维矩阵是否为奇数的bool值：\n", dim_two % 2 == 1)

dim_one[:] = 0
print("一维矩阵清零后：", dim_one)

# 3.矩阵合并
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print("[1, 2], [3, 4] 和 [5, 6], [7, 8] 横向合并：\n", np.hstack((a, b)))
print("[1, 2], [3, 4] 和 [5, 6], [7, 8] 纵向合并：\n", np.vstack((a, b)))
# np.concatenate( (a1,a2), axis=0 ) 等价于 np.vstack( (a1,a2) )
# np.concatenate( (a1,a2), axis=1 ) 等价于 np.hstack( (a1,a2) )

# 4.通过函数创建矩阵
# arange()
print("arange(10)：", np.arange(10)) # 默认从0开始到10（不包括10），步长为1
print("arange(5, 10)：", np.arange(5, 10)) # 从5开始到10（不包括10），步长为1
print("arange(5, 20, 2)：", np.arange(5, 20, 2)) # 从5开始到20（不包括20），步长为2

# linspqce()
print("linspace(0, 10, 5)：", np.linspace(0, 10, 5)) # 用于创建指定数量等间隔的序列，实际生成一个等差数列

# logspace()
print("logspace(4, 8, 5)：", np.logspace(4, 8, 5)) # 用于生成等比数列,4表示10的4次方，8表示10的8次方

# zeros、ones、eye、empty
print("zeros((3, 3))：\n", np.zeros((3, 3))) # 创建3*3的全0矩阵
print("ones((3, 3))：\n", np.ones((3, 3))) # 创建3*3的全1矩阵
print("eye(3)：\n", np.eye(3)) # 创建3*3的单位矩阵
print("empty((3, 4))：\n", np.empty((3, 4))) # 创建3*4的空矩阵

# fromstring()
print("np.fromstring(abcdef, dtype = np.int8)：", np.fromstring("abcdef", dtype = np.int8))

# fromfunction()
def func(i, j):
    return i + j;
print("np.fromfunction(func, (3, 3)：\n", np.fromfunction(func, (3, 3)))

# 5.矩阵的运算
# 常用矩阵运算
m = np.array([[4, 5, 6], [1, 2, 3]])
n = np.array([[6, 5, 4], [3, 2, 1]])

print("array + ：\n", m + n) # +，矩阵对应元素相加
print("array - ：\n", m - n) # -，矩阵对应元素相减
print("array * ：\n", m * n) # *，矩阵对应元素相乘
print("array / ：\n", m / n) # /，矩阵对应元素相除，如果都是整数则取商
print("array % ：\n", m % n) # %，矩阵对应元素相除后取余数
print("array ** ：\n", m**2) # **，矩阵每个元素都取n次方，如**2：每个元素都取平方

# 常用矩阵函数
x = np.ones(1)

print("sin：", np.sin(x)) # 对矩阵x中每个元素取正弦,sin(x)
print("cos：", np.cos(x)) # 对矩阵x中每个元素取余弦,cos(x)
print("tan：", np.tan(x)) # 对矩阵x中每个元素取正切,tan(x)
print("arcsin：", np.arcsin(x)) # 对矩阵x中每个元素取反正弦,arcsin(x)
print("arccos：", np.arccos(x)) # 对矩阵x中每个元素取反余弦,arccos(x)
print("arctan：", np.arctan(x)) # 对矩阵x中每个元素取反正切,arctan(x)
print("exp：", np.exp(x)) # 对矩阵x中每个元素取指数函数,exp(x)
print("sqrt：", np.sqrt(x)) # 对矩阵x中每个元素开根号sqrt(x)

# 矩阵点乘，矩阵乘法必须满足矩阵乘法的条件，即第一个矩阵的列数等于第二个矩阵的行数。 矩阵乘法的函数为 dot 
m = np.array([[1,2,3],[4,5,6]]) # m为2*3矩阵
n = np.array([[1,2],[3,4],[5,6]]) # n为3*2矩阵

if m.shape[1] == n.shape[0]:
    print("[1,2,3],[4,5,6] 乘 [1,2],[3,4],[5,6]：\n", m.dot(n))
else:
    print("矩阵无法相乘!!!")

# 矩阵转置
print("矩阵转置transpose()：\n", m.transpose())
print("矩阵转置.T：\n", m.T)

# 逆矩阵 Array-1，矩阵求逆的条件是矩阵的行数和列数相同
import numpy.linalg as lg
x = np.eye(3)
print("eye(3) 逆矩阵：\n", lg.inv(x))

# 6.矩阵信息获取（如：平均值、方差……）
#   axis=0 行方向最大（小）值，即获得每列的最大（小）值组成的矩阵
#   axis=1 列方向最大（小）值，即获得每行的最大（小）值组成的矩阵
x = np.array([[7,5,3],[2,4,6]])

# 最大最小值。可以指定关键字参数axis来获得行最大（小）值或列最大（小）值
# 要想获得最大最小值元素所在的位置，可以通过argmax函数来获得，下标从0开始,若没有axis则转换为一维矩阵
print("[7,5,3],[2,4,6]矩阵最大值：", x.max())
print("[7,5,3],[2,4,6]矩阵最小值：", x.min())
print("[7,5,3],[2,4,6]矩阵列最大值：", x.max(axis = 0))
print("[7,5,3],[2,4,6]矩阵行最大值：", x.max(axis = 1))
print("[7,5,3],[2,4,6]矩阵列最大值位置：", x.argmin(axis = 0))
print("[7,5,3],[2,4,6]矩阵行最大值位置", x.argmin(axis = 1))

# 平均值
print("[7,5,3],[2,4,6]矩阵平均值：", x.mean())
print("[7,5,3],[2,4,6]矩阵列平均值：", x.mean(axis = 0))
print("[7,5,3],[2,4,6]矩阵行平均值：", x.mean(axis = 1))

# 方差，方差的函数为var(),方差函数var()相当于函数mean(abs(x - x.mean())**2),其中x为矩阵
print("[7,5,3],[2,4,6]矩阵方差：", x.var())
print("[7,5,3],[2,4,6]矩阵列方差：", x.var(axis = 0))
print("[7,5,3],[2,4,6]矩阵行方差：", x.var(axis = 1))

# 标准差，标准差的函数为std()。 std()相当于sqrt(mean(abs(x - x.mean())**2))，或相当于sqrt(x.var())
print("[7,5,3],[2,4,6]矩阵标准差：", x.std())
print("[7,5,3],[2,4,6]矩阵列标准差：", x.std(axis = 0))
print("[7,5,3],[2,4,6]矩阵行标准差：", x.std(axis = 1))

# 中值，中值指的是将序列按大小顺序排列后，排在中间的那个值，如果有偶数个数，则是排在中间两个数的平均值
print("[7,5,3],[2,4,6]矩阵中值：", np.median(x))
print("[7,5,3],[2,4,6]矩阵列中值：", np.median(x, axis = 0))
print("[7,5,3],[2,4,6]矩阵行中值：", np.median(x, axis = 1))

# 求和
print("[7,5,3],[2,4,6]矩阵求和：", x.sum())
print("[7,5,3],[2,4,6]矩阵列求和：", x.sum(axis = 0))
print("[7,5,3],[2,4,6]矩阵行求和", x.sum(axis = 1))

# 累积和，某位置累积和指的是该位置之前(包括该位置)所有元素的和
print("[7,5,3],[2,4,6]矩阵累积和：", x.cumsum())
print("[7,5,3],[2,4,6]矩阵列累积和：\n", x.cumsum(axis = 0))
print("[7,5,3],[2,4,6]矩阵行累积和：\n", x.cumsum(axis = 1))