数据分析(基础/数组)
一什么是数据分析?
二使用python做数据分析的常用库
-
numpy 基础数值算法
-
scipy 科学计算
-
matplotlib 数据可视化
-
pandas 序列高级函数
三numpy概述
-
Numerical Python,数值的Python,补充了Python语言所欠缺的数值计算能力。
-
Numpy是其它数据分析及机器学习库的底层库。
-
Numpy完全标准C语言实现,运行效率充分优化。
-
Numpy开源免费。
(一)numpy历史
-
1995年,Numeric,Python语言数值计算扩充。
-
2001年,Scipy->Numarray,多维数组运算。
-
2005年,Numeric+Numarray->Numpy。
-
2006年,Numpy脱离Scipy成为独立的项目。
(二)numpy的核心:多维数组
-
代码简洁:减少Python代码中的循环。
-
底层实现:厚内核(C)+薄接口(Python),保证性能。
#numpy演示 import numpy as np ary = np.array([1, 2, 3, 4, 5, 6]) print(ary, type(ary)) print(ary + 10) print(ary * 3) print(ary + ary) """ [1 2 3 4 5 6] <class 'numpy.ndarray'> [11 12 13 14 15 16] [ 3 6 9 12 15 18] [ 2 4 6 8 10 12] """
内存中的ndarray对象
存储对目标数组的描述信息,如:dim count、dimensions、dtype、data等。
实际数据
完整的数组数据
将实际数据与元数据分开存放,一方面提高了内存空间的使用效率,另一方面减少对实际数据的访问频率,提高性能。
2.ndarray数组对象的特点
- Numpy数组是同质数组,即所有元素的数据类型必须相同
- Numpy数组的下标从0开始,最后一个元素的下标为数组长度减1
3.ndarray数组对象的创建
np.array(任何可被解释为Numpy数组的逻辑结构)
import numpy as np a = np.array([1, 2, 3, 4, 5, 6]) print(a) # [1 2 3 4 5 6]
np.arange(起始值(0),终止值,步长(1))
import numpy as np a = np.arange(0, 5, 1) print(a) # [0 1 2 3 4] b = np.arange(0, 10, 2) print(b) # [0 2 4 6 8]
np.zeros(数组元素个数, dtype='类型')
import numpy as np a = np.zeros(10) print(a) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] b = np.zeros(10, dtype='float32') print(b) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
np.ones(数组元素个数, dtype='类型')
import numpy as np a = np.ones(10) print(a) # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] b = np.ones((3, 3, 4), dtype='int32')#三页 三行 四列 print(b) """ [[[1 1 1 1] [1 1 1 1] [1 1 1 1]] [[1 1 1 1] [1 1 1 1] [1 1 1 1]] [[1 1 1 1] [1 1 1 1] [1 1 1 1]]] """ # 创建一个结构像b的数组 元素都为0 e = np.zeros_like(b) print(e) #创建5个五分之一的数组 print(np.ones(5)/5) # [0.2 0.2 0.2 0.2 0.2]
数组的维度:np.ndarray.shape
import numpy as np ary = np.array([1, 2, 3, 4, 5, 6]) print(type(ary), ary, ary.shape) # <class 'numpy.ndarray'> [1 2 3 4 5 6] (6,) #二维数组 ary = np.array([ [1,2,3,4], [5,6,7,8] ]) print(type(ary), ary, ary.shape) #<class 'numpy.ndarray'> [[1 2 3 4] [5 6 7 8]] (2, 4)
import numpy as np ary = np.array([1, 2, 3, 4, 5, 6]) print(type(ary), ary, ary.dtype) #<class 'numpy.ndarray'> [1 2 3 4 5 6] int64
#转换ary元素的类型 b = ary.astype(float) print(type(b), b, b.dtype) #<class 'numpy.ndarray'> [1. 2. 3. 4. 5. 6.] float64 #转换ary元素的类型 c = ary.astype('str') print(type(c), c, c.dtype) #<class 'numpy.ndarray'> ['1' '2' '3' '4' '5' '6'] <U21
import numpy as np # 维度 ary = np.arange(1, 7) print(ary, ary.shape) #[1 2 3 4 5 6] (6,) ary.shape = (2, 3) print(ary, ary.shape) """ [[1 2 3] [4 5 6]] (2, 3) """ # 元素的数据类型 print(ary, ary.dtype) """ [[1 2 3] [4 5 6]] int64 """ # ary.dtype = 'int64' # print(ary, ary.dtype) ary = ary.astype('float64') print(ary, ary.dtype) """ [[1. 2. 3.] [4. 5. 6.]] float64 """
import numpy as np ary = np.array([ [1,2,3,4], [5,6,7,8] ]) #观察维度,size,len的区别 print(ary.shape, ary.size, len(ary)) # (2, 4) 8 2
数组元素索引(下标)
数组对象[..., 页号, 行号, 列号]
下标从0开始,到数组len-1结束。
import numpy as np a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) print(a, a.shape) """ [[[1 2] [3 4]] [[5 6] [7 8]]] (2, 2, 2) 两页 两行 两列 """ print(a[0]) """ [[1 2] [3 4]] """ print(a[0][0]) #[1 2] print(a[0][0][0]) #1 print(a[0, 0, 0]) #1 for i in range(a.shape[0]): #循环页 for j in range(a.shape[1]): #循环行 for k in range(a.shape[2]): #循环列 print(a[i, j, k]) """ 1 2 3 4 5 6 7 8 """
类型名 | 类型表示符 |
---|---|
布尔型 | bool_ |
有符号整数型 | int8(-128~127)/int16/int32/int64 |
无符号整数型 | uint8(0~255)/uint16/uint32/uint64 |
浮点型 | float16/float32/float64 |
复数型 | complex64/complex128 |
字串型 | str_,每个字符用32位Unicode编码表示 |
# 自定义复合类型 import numpy as np data=[ ('zs', [90, 80, 85], 15), ('ls', [92, 81, 83], 16), ('ww', [95, 85, 95], 15) ] #第一种设置dtype的方式 a = np.array(data, dtype='U3, 3int32, int32') print(a) # [('zs', [90, 80, 85], 15) ('ls', [92, 81, 83], 16) ('ww', [95, 85, 95], 15)] print(a[0][0], ":", a[1][1]) # zs : [92 81 83] print("=====================================") #第二种设置dtype的方式 b = np.array(data, dtype=[('name', 'str_', 2), ('scores', 'int32', 3), ('ages', 'int32', 1)]) print(b[0]['name'], ":", b[0]['scores']) # zs : [90 80 85] print("=====================================") #第三种设置dtype的方式 c = np.array(data, dtype={'names': ['name', 'scores', 'ages'],'formats': ['U3', '3int32', 'int32']}) print(c[0]['name'], ":", c[0]['scores'], ":", c.itemsize) # zs : [90 80 85] : 28 print("=====================================") #第四种设置dtype的方式 d = np.array(data, dtype= {'name': ('U3', 0), 'scores': ('3i4', 16), #('3int32', 16) 'age': ('i4', 28)}) # ('int32', 28) print(d[0]['name'], d[0]['scores'], d.itemsize) # zs [90 80 85] 32 print("=====================================") #第五种设置dtype的方式 e = np.array([0x1234, 0x5667], dtype=('u2', {'lowc': ('u1', 0), 'hignc': ('u1', 1)})) print('%x' % e[0]) #1234 print('%x %x' % (e['lowc'][0], e['hignc'][0])) #34 12 print("=====================================") #测试日期类型数组 f = np.array(['2011', '2012-01-01', '2013-01-01 01:01:01','2011-02-01']) f = f.astype('M8[D]') print(f) #['2011-01-01' '2012-01-01' '2013-01-01' '2011-02-01'] f = f.astype('int32') print(f) #[14975 15340 15706 15006] print(f[3]-f[0]) #31 a = np.array([[1 + 1j, 2 + 4j, 3 + 7j], [4 + 2j, 5 + 5j, 6 + 8j], [7 + 3j, 8 + 6j, 9 + 9j]]) print(a.T) """ [[1.+1.j 4.+2.j 7.+3.j] [2.+4.j 5.+5.j 8.+6.j] [3.+7.j 6.+8.j 9.+9.j]] """ for x in a.flat: print(x.imag) """ 1.0 4.0 7.0 2.0 5.0 8.0 3.0 6.0 9.0 """
类型字符码
类型 | 字符码 |
---|---|
np.bool_ | ? |
np.int8/16/32/64 | i1/i2/i4/i8 |
np.uint8/16/32/64 | u1/u2/u4/u8 |
np.float/16/32/64 | f2/f4/f8 |
np.complex64/128 | c8/c16 |
np.str_ | U<字符数> |
np.datetime64 | M8[Y] M8[M] M8[D] M8[h] M8[m] M8[s] |
字节序前缀,用于多字节整数和字符串:
</>/[=]分别表示小端/大端/硬件字节序。
类型字符码格式:
<字节序前缀><维度><类型><字节数或字符数>
3i4 | 释义 |
---|---|
3i4 | 大端字节序,3个元素的一维数组,每个元素都是整型,每个整型元素占4个字节。 |
<(2,3)u8 | 小端字节序,6个元素2行3列的二维数组,每个元素都是无符号整型,每个无符号整型元素占8个字节。 |
U7 | 包含7个字符的Unicode字符串,每个字符占4个字节,采用默认字节序。 |
ndarray数组对象的维度操作
import numpy as np # 视图变维 reshape() 与 ravel() a = np.arange(1, 10) print(a, a.shape) #[1 2 3 4 5 6 7 8 9] (9,) a = a.reshape(3, 3) print(a, a.shape) """ [[1 2 3] [4 5 6] [7 8 9]] (3, 3) """ b = a.ravel()#共享抻平 print(b, b.shape)#[1 2 3 4 5 6 7 8 9] (9,) b[0] = 999 print(a,a.shape)#视图变维,数据共享 """ [[999 2 3] [ 4 5 6] [ 7 8 9]] (3, 3) """ #复制变维 (数据独立) :flatten() copy() c= a.flatten() # c[999,2,3,4,...] 复制抻平 print(c) #[999 2 3 4 5 6 7 8 9] a[0][0] = 1 print(c) #[999 2 3 4 5 6 7 8 9] print(a) """ [[1 2 3] [4 5 6] [7 8 9]] """ #就地变维 a.shape = (-1,9)#N行9列 print(a,a.shape) #[[1 2 3 4 5 6 7 8 9]] (1, 9) a.resize(3,3)#3行3列 print(a,a.shape) """ [[1 2 3] [4 5 6] [7 8 9]] (3, 3) """
数组对象切片的参数设置与列表切面参数类似
步长+:默认切从首到尾
步长-:默认切从尾到首
数组对象[起始位置:终止位置:步长]
默认位置步长:1
import numpy as np a = np.arange(1, 10) print(a) # 1 2 3 4 5 6 7 8 9 print(a[:3]) # 1 2 3 print(a[3:6]) # 4 5 6 print(a[6:]) # 7 8 9 print(a[::-1]) # 9 8 7 6 5 4 3 2 1 print(a[:-4:-1]) # 9 8 7 print(a[-4:-7:-1]) # 6 5 4 print(a[-7::-1]) # 3 2 1 print(a[::]) # 1 2 3 4 5 6 7 8 9 print(a[:]) # 1 2 3 4 5 6 7 8 9 print(a[::3]) # 1 4 7 print(a[1::3]) # 2 5 8 print(a[2::3]) # 3 6 9
多维数组的切片操作
import numpy as np a = np.arange(1, 28) a.resize(3,3,3) print(a) """ [[[ 1 2 3] [ 4 5 6] [ 7 8 9]] [[10 11 12] [13 14 15] [16 17 18]] [[19 20 21] [22 23 24] [25 26 27]]] """ #切出1页 print(a[1, :, :]) """ [[10 11 12] [13 14 15] [16 17 18]] """ #切出所有页的1行 print(a[:, 1, :]) """ [[ 4 5 6] [13 14 15] [22 23 24]] """ #切出0页的1行1列 print(a[0, :, 1]) #[2 5 8]
import numpy as np a = np.arange(1, 10) mask = [True, False,True, False,True, False,True, False,True] print(a[mask]) #[1 3 5 7 9]
import numpy as np a = np.arange(1, 100) # 获取100以内3的倍数 mask = (a % 3 == 0) | (a % 7 == 0) print(a[mask]) """ [ 3 6 7 9 12 14 15 18 21 24 27 28 30 33 35 36 39 42 45 48 49 51 54 56 57 60 63 66 69 70 72 75 77 78 81 84 87 90 91 93 96 98 99] """ #mask 作为下标掩码 b = np.array([90,80,60,30]) mask = np.array([3,2,1,0,3,2,0,1,2,3,0]) print(b[mask]) #[30 60 80 90 30 60 90 80 60 30 90] indices = b.argsort()# 排序后返回有序索引 print(indices) #[3 2 1 0]
a = np.arange(1, 7).reshape(2, 3) b = np.arange(7, 13).reshape(2, 3)
# 水平方向操作 c = np.hstack((a, b)) print(c) """ [[ 1 2 3 7 8 9] [ 4 5 6 10 11 12]] """ a, b = np.hsplit(c, 2) # 把c沿水平方向拆2份 print(a) """ [[1 2 3] [4 5 6]] """ print(b) """ [[ 7 8 9] [10 11 12]] """
import numpy as np a = np.arange(1, 7).reshape(2, 3) b = np.arange(7, 13).reshape(2, 3) # 垂直方向操作 c = np.vstack((a, b)) print(c) """ [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]] """ a, b = np.vsplit(c, 2) # 把c沿垂直方向拆2份 print(a) """ [[1 2 3] [4 5 6]] """ print(b) """ [[ 7 8 9] [10 11 12]] """
import numpy as np a = np.arange(1, 7).reshape(2, 3) b = np.arange(7, 13).reshape(2, 3) # 深度方向操作(上帝视角) c = np.dstack((a, b)) print(c) """ [[[ 1 7] [ 2 8] [ 3 9]] [[ 4 10] [ 5 11] [ 6 12]]] """ a, b = np.dsplit(c, 2) # 把c沿深度方向拆2份 print(a) """ [[[1] [2] [3]] [[4] [5] [6]]] """ print(b) """ [[[ 7] [ 8] [ 9]] [[10] [11] [12]]] """
# 通过axis作为关键字参数指定组合的方向,取值如下: # 若待组合的数组都是二维数组: # 0: 垂直方向组合 # 1: 水平方向组合 # 若待组合的数组都是三维数组: # 0: 垂直方向组合 # 1: 水平方向组合 # 2: 深度方向组合 np.concatenate((a, b), axis=0) # 通过给出的数组与要拆分的份数,按照某个方向进行拆分,axis的取值同上 np.split(c, 2, axis=0)
# 数组头尾补全 a = np.array([1,2,3,4,5,6]) b = np.array([8,8,8,8]) # 填充b数组使其长度与a相同 b = np.pad(b, pad_width=(1,1), mode='constant', constant_values=-1) print(b) #[-1 8 8 8 8 -1] # 垂直方向完成组合操作,生成新数组 c = np.vstack((a, b)) print(c) """ [[ 1 2 3 4 5 6] [-1 8 8 8 8 -1]] """
简单的一维数组组合方案
import numpy as np # 一维数组的组合方案: a = np.arange(10, 20) b = np.arange(20, 30) print(a)#[10 11 12 13 14 15 16 17 18 19] print(b)#[20 21 22 23 24 25 26 27 28 29] c = np.row_stack((a, b)) print(c) """ [[10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29]] """ d = np.column_stack((a, b)) print(d) """ [[10 20] [11 21] [12 22] [13 23] [14 24] [15 25] [16 26] [17 27] [18 28] [19 29]] """
-
-
dtype - 元素类型
-
size - 元素数量
-
ndim - 维数,len(shape)
-
itemsize - 元素字节数
-
nbytes - 总字节数 = size x itemsize
-
real - 复数数组的实部数组
-
imag - 复数数组的虚部数组
-
T - 数组对象的转置视图
-
flat - 扁平迭代器
import numpy as np a = np.array([[1 + 1j, 2 + 4j, 3 + 7j], [4 + 2j, 5 + 5j, 6 + 8j], [7 + 3j, 8 + 6j, 9 + 9j]]) print(a.shape)#(3, 3) print(a.dtype)#complex128 print(a.ndim)#2 print(a.size)#9 print(a.itemsize)#16 print(a.nbytes)#144 print(a.real, a.imag, sep='\n') """ [[1. 2. 3.] [4. 5. 6.] [7. 8. 9.]] [[1. 4. 7.] [2. 5. 8.] [3. 6. 9.]] """ print(a.T) """ [[1.+1.j 4.+2.j 7.+3.j] [2.+4.j 5.+5.j 8.+6.j] [3.+7.j 6.+8.j 9.+9.j]] """ print([elem for elem in a.flat]) b = a.tolist() print(b) """ [(1+1j), (2+4j), (3+7j), (4+2j), (5+5j), (6+8j), (7+3j), (8+6j), (9+9j)] [[(1+1j), (2+4j), (3+7j)], [(4+2j), (5+5j), (6+8j)], [(7+3j), (8+6j), (9+9j)]] """