数据可视化学习笔记【一】(numpy包)
编译器为 Spyder 3.3.6 自带所需要使用的所有安装包。
Cpt 1. numpy
模块
1. 数组的定义以及数组属性的查看
数组的定义:数组形式上与列表相同,但内部的所有元素的类型必须相同(全为整数或字符)。
np.empty()
:空数组的生成。括号里写生成的大小(多维则输入元组形式)生成的数是无限接近于0的,但不是0;np.zeros()
:全0数组的生成。括号内填发与空数组相同;np.ones()
:全1数组的生成。如上;np.random.randint(最大值, size = (元组))
:随机数组的生成。这里的size
与生成空数组的写法一样。
import numpy as np
A = np.empty(5)
B = np.random.randint(100, size = (4,6))
print("一维空数组:\n", A)
print("二维随机数组:\n", B)
>>>一维数组:
[1.06099790e-313 1.16709769e-312 2.12199579e-313 4.24399161e-314 1.25197752e-312]
>>>二维数组:
[[64 39 18 15 56 22]
[14 33 16 81 48 2]
[16 2 61 94 98 2]
[50 59 30 70 86 20]]
如代码所示,输出的是一个列表,可以如列表一样,通过索引读取内部的值。可以通过以下几个操作获取这个数组的信息:
数组有几个不同的信息:
- 数据的类型
dtype
返回的是int
、bool
、float
、char
等数值表示类型; - 维度
shape
返回的是数组的大小(是一个元组),具有几行几列的信息; - 维数
ndim
返回的是数组是几维的(是一个数值),也就是len(item.shape)
; - 数组内元素个数
size
:也就是shape
中所有元素的乘积; - 每个元素占据内存的大小
itemsize
与dtype
有关,比如如下的是int4
就是 位,占据 个byte
。 - 数组占据内存的大小
nbytes
,就是每个元素占据内存的大小 元素个数。
item = B
print("dtype={}, ndim={}, shape={}, size={}, itemsize={}, nbytes={}".\
format(item.dtype, item.ndim, item.shape, item.size, item.itemsize, item.nbytes))
>>> dtype=int32, ndim=2, shape=(4, 6), size=24, itemsize=4, nbytes=96
2. 数组的索引:
数组的索引与 python
内部列表数据结构完全一样。
补充操作:二维数组的取某一行或列
取某一行的操作其实可以通过列表中的索引来表示,然而取列的操作较为麻烦,这里引入了新的方法:
C = np.zeros((4,6))
i = 2
print(C[i,:])
print(C[:,i])
>>> [0. 0. 0. 0. 0. 0.]
>>> [0. 0. 0. 0.]
数组的切片产生的是视图,而不是重复生成一个数据,对他的改变就改变原数据。如果需要得到一个新的数据,那么需要使用 copy
函数得到一个相同的数据。
Remark:一定要注意:取出来的一定要是一个列表,不能是一个元素,如果只有一个元素,那就是一个复制。
C = np.zeros((4,6))
C2 = C[1:3, 1].copy()
print(C)
C2[0] = 4
print(C)
>>>[[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]]
>>>[[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]]
使用了 copy
函数可以发现,并没有改变原数组的值。
3. 改变矩阵形状
矩阵转置和拉伸
数据处理中较为重要的:newaxis()
函数,在数据处理中进行转置操作:(或将一个
矩阵拉成
的向量,用于计算
乘积,可以使用reshape()
函数,使用方法:xxx.reshape((1,9))
)
D = np.arange(10)
print(D)
D = D[:, np.newaxis]
print(D)
>>>[0 1 2 3 4 5 6 7 8 9]
>>>[[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]]
扩展一组基
数组的拼接:(扩展一组基)用法:vstack
纵向的(在下方),hstack
横向的(在右边)。输入必须得是列表格式。
A1 = np.zeros((3,5))
A2 = np.ones((3,5))
A3 = np.vstack([A1, A2])
print(A3)
>>>[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
分裂
使用 split
函数,第二个参数写分裂的区间:[3]
表示分裂到第三行(也就是列表的第四行),如果写的是 [2,4]
那就是 [0~1],[2~4],[5~end]
一共三个区间。
如果要改变方向,改变 axis
的值,如果是 0
或者默认,那就按列,如果是 1
那就按行。
a1, a2 = np.split(A3, [3], axis = 0)
print("上半部分:\n", a1)
print("下半部分:\n", a2)
>>>上半部分:
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
>>>下半部分:
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
4. 向量化运算
np.add
、np.mod
、…等,前缀加上 np
即可,或是一些简单的运算如
、
、
、
、整除、取模等都可以用原来的表示方法来表示。
all
和 any
用来判断是否这个矩阵中全部、或至少有一个满足这个条件
A = np.arange(0,10).reshape([2,5])
print(np.any(A>10))
print(np.any(A>5))
print(np.all(A>5))
print(np.all(A>0))
>>> False
>>> True
>>> False
>>> False
Filter
的实现:选取矩阵中满足特定条件的元素,返回的值为一个一维数组。
A = np.arange(0,10).reshape([2,5])
A1 = A[A>5]
print(A1)
>>> [6 7 8 9]
运用 np.multiply
这类函数,可以将最终值赋给另一个元素,而这里我特意看了一下,b
和 c
不仅值相同,而且他们的地址都是一致的,他们代表着同一个变量。
a = np.arange(10)
b = np.empty(10)
c = np.multiply(a, 2, out=b)
print(a)
print(b)
print(c)
print(b is c)
>>> [0 1 2 3 4 5 6 7 8 9]
>>> [ 0. 2. 4. 6. 8. 10. 12. 14. 16. 18.]
>>> [ 0. 2. 4. 6. 8. 10. 12. 14. 16. 18.]
>>> True
5. 矩阵乘积的实现
矩阵乘积:矩阵运算中的乘积:
A = np.arange(0,4).reshape([2,2])
B = np.arange(0,6).reshape([2,3])
C = A@B
# C = np.dot(A,B) 也可以
print(C)
>>> [[ 3 4 5]
[ 9 14 19]]
乘积: 与 的维数必须相同,然后两者乘积为相应元素之间乘积:
E = np.arange(0,6).reshape([2,3])
F = np.arange(0,6).reshape([2,3])
H = E*F
print(H)
>>>[[ 0 1 4]
[ 9 16 25]]
乘积:如果 ,那 。这个乘积具有很好的性质,比如算某些特殊矩阵的特征值等会经常用到。
在 python
中使用 multiply.outer
函数表示:
K = np.multiply.outer(A,B)
print(K)
>>> [[[[ 0 0 0]
[ 0 0 0]]
[[ 0 1 2]
[ 3 4 5]]]
[[[ 0 2 4]
[ 6 8 10]]
[[ 0 3 6]
[ 9 12 15]]]]
最后就能够得到一个高维矩阵。然后后续得自己处理一下才能得到矩阵形式。