数据科学入门
matplotlib模块
二维直线图
import numpy as np
from matplotlib import pyplot as plt
# 生成一个-3到3的等差数列,共100个数
a = np.linspace(-3, 3, 10)
# 三角函数
b = np.sin(a)
plt.plot(a, b)
# 等价于 plt.plot(b)
plt.show() # 正弦图
绘制多条数据线
# 画出多条数据线:
plt.plot(a, np.sin(a))
plt.plot(a, np.sin(2 * a))
plt.show()
线条修饰
# 使用字符串,给定线条参数:
# b:蓝色
# -- : 虚线
# o : 圆点
'''
完整参数可参考
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot
'''
plt.plot(a, np.sin(a), 'b--o')
plt.show()
散点图
plt.plot(a, np.sin(a), 'bo')
plt.show() # 二维散点图
# 等价于
plt.scatter(a, np.sin(a),color='blue',marker='o')
plt.show()
t = np.linspace(0, 2 * np.pi, 50)
x = np.sin(t)
plt.plot(t, x, 'bo', t, np.sin(2 * t), 'r-^', label='sin', color='red', )
plt.legend()
plt.xlabel('radians')
plt.ylabel('amplitude', fontsize='large')
plt.title('Sin(x)')
plt.grid()
plt.show()
# 直方图
data = np.array([1234, 321, 400, 120, 11, 30, 2000])
plt.hist(data, 7)
plt.show()
绘制三 维数据
# 高维 RBF 插值
# 三维数据点:
import numpy as np
from matplotlib import pyplot as plt
x, y = np.mgrid[-np.pi / 2:np.pi / 2:5j, -np.pi / 2:np.pi / 2:5j]
z = np.cos(np.sqrt(x ** 2 + y ** 2))
fig = plt.figure(figsize=(12, 6))
ax = fig.add_subplot(projection='3d')
ax.scatter(x, y, z)
fig.savefig("mplot3d.jpg")
plt.show()
直方图
import numpy as np
from matplotlib import pyplot as plt
# 正态分布
from scipy.stats import norm
x_norm = norm.rvs(size=500)
x_norm.shape
plt.ion() #开启interactive mode
h = plt.hist(x_norm)
print('counts, ', h[0])
print('bin centers', h[1])
figure = plt.figure(1) # 创建图表1
plt.show()
归一化直方图(用出现频率代替次数),将划分区间变为 20(默认 10):
h = plt.hist(x_norm, bins=20)
plt.show()
多组直方图
from scipy.stats import norm
from scipy.stats import ttest_ind
# 独立样本 t 检验
# 两组参数不同的正态分布:
n1 = norm(loc=0.3, scale=1.0)
n2 = norm(loc=0, scale=1.0)
# 从分布中产生两组随机样本:
n1_samples = n1.rvs(size=100)
n2_samples = n2.rvs(size=100)
# 将两组样本混合在一起:
samples = np.hstack((n1_samples, n2_samples))
# 最大似然参数估计:
loc, scale = norm.fit(samples)
n = norm(loc=loc, scale=scale)
# 比较:
x = np.linspace(-3, 3, 100)
plt.hist([samples, n1_samples, n2_samples])
plt.plot(x, n.pdf(x), 'b-')
plt.plot(x, n1.pdf(x), 'g-')
plt.plot(x, n2.pdf(x), 'r-')
plt.show()
离散分布
# 离散分布
from scipy.stats import randint
# 离散均匀分布的概率质量函数(PMF):
high = 10
low = -10
x = np.arange(low, high + 1, 0.5)
p = plt.stem(x, randint(low, high).pmf(x)) # 杆状图
plt.show()
图内填充
from scipy.integrate import trapz
x1 = np.linspace(-2, 2, 108)
p = trapz(norm.pdf(x1), x1)
print('{:.2%} of the values lie between -2 and 2'.format(p))
plt.fill_between(x1, norm.pdf(x1), color='red')
plt.plot(x, norm.pdf(x), 'k-')
plt.show()
Numpy数组
数组:array
很多其他科学计算的第三方库都是以Numpy为基础建立的。
Numpy的一个重要特性是它的数组计算。
使用前一定要先导入 Numpy 包,导入的方法有以下几种:
import numpy
import numpy as np
from numpy import *
from numpy import array, sin
导入numpy,最常用为这种:
import numpy as np
假如我们想将列表中的每个元素增加1,但列表不支持这样的操作(报错):
a = [1, 2]
# a + 1 # 报错
使用numpy.array:
a = np.array(a)
a # [1 2]
b = a + 1
b # array([2,3])
与另一个 array 相加,得到对应元素相加的结果:
c = a + b
print(c) # array([3,5])
# 对应元素相乘:
print(a * b) # [2 6]
# 对应元素乘方:
print(a ** b) # [1 8]
数组的合并
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.arange(2) # np.array([0, 1])
print(a, b)
'''[[1 2]
[3 4]] [0 1]'''
# 正确的做法是:
np.append(a, b) # array([1, 2, 3, 4, 0, 1])
# 错误的做法是:
print(list(a)+ list(b)) # [array([1, 2]), array([3, 4]), 0, 1]
提取数组中的元素
# 提取第一个
a = np.array([1, 2, 3, 4])
print(a[0]) # 1
# 提取前两个元素:
print(a[:2]) # [1 2]
# 最后两个元素
print(a[-2:]) # [3 4]
# 相加:
print(a[:2] + a[-2:]) # [4 6]
修改数组形状
查看array的形状:
b = a.shape
b # (4,)
# 修改 array 的形状:
a.shape = 2, 2
a
# [[1 2]
# [3 4]]
# 多维数组
# a 现在变成了一个二维的数组,可以进行加法:
a + a
# [[2 4]
# [6 8]]
# 乘法仍 然是对应元素的乘积,并不是按照矩阵乘法来计算:
a * a
# [[ 1 4]
# [ 9 16]]
Numpy索引:index
import numpy as np
# 查看形状,会返回一个元组,每个元素代表这一维的元素数目:
a = np.array([1, 2, 3, 5])
# 1维数组,返回一个元组
a.shape
# 查 看元素数目:
a.size
使用fill方法设定初始值
可以使用 fill 方法将数组设为指定值:
print(a)
a.fill(-4)
print(a)
# 切片,支持负索引:
a = np.array([11, 12, 13, 14, 15])
print(a[1:-2]) # [12 13]
# 省略参数:
print(a[::2]) # [11 13 15]
print(a[-2:]) # array([14, 15])
假设我们记录一辆汽车表盘上每天显示的里程数:
rec = np.array([21000, 21180, 21240, 22100, 22400])
dist = rec[1:] - rec[:-1] # 后一天减去前一天的
dist
多维数组的索引
a = np.array([[1, 2, 3], [7, 8, 9]])
a
# 查看形状:
print(a.shape)
# 查看总的元素个数:
print(a.size)
# 查看维数:
print(a.ndim)
# 对于二维数组,可以传入两个数字来索引:
print(a[1, 1])
# 索引一整行内容:
print(a[0])
多维数组的复杂一点的例子:
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
# 想得到第一行的第 4 和第 5 两个元素:
print(a[0, 3:5]) # [3 4]
# 得到最后两行的最后两列:
print(a[4:, 4:]) # [[44 45][54 55]]
# 得到第三列:
print(a[:, 2]) # [ 2 12 22 32 42 52]
取出3,5行的奇数列:
b = a[2::2, ::2]
b
切片在内存中使用的是引用机制
引用机制意味着,Python并没有为 b 分配新的空间来存储它的值, 而是让 b 指向了 a 所分配的内存空间,因此,改变 b 会改变 a 的值:
a = np.array([0, 1, 2, 3, 4])
b = a[2:4]
b
b[0] = 10
b
a
# 而这种现象在列表中并不会出现:
b = a[2:3]
b[0] = 12
print(a)
# 解决方法是使用copy()方法产生一个复制,这个复制会申请新的内存:
b = a[2:4].copy()
b[0] = 10
print(a, b)
一维花式索引
与 range 函数类似,我们可以使用 arange 函数来产生等差数组。
a = np.arange(0, 80, 10)
a
# 花式索引需要指定索引位置:
indices = [1, 2, -3]
y = a[indices]
y
# 还可以使用布尔数组来花式索引:
mask = np.array([0, 1, 1, 0, 0, 1, 0, 1], dtype=bool)
a[mask] # [10 20 50 70]
选出了所有大于0.5的值:
from numpy.random import rand
a = rand(10)
a
mask = a > 0.5
a[mask]
“不完全”索引
只给定行索引的时候,返回整行:
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
b = a[:3]
b
# 这时候也可以使用花式索引取出第2,3,5行:
condition = np.array([0, 1, 1, 0, 1, 0], dtype=bool)
c = a[condition]
c
where语句
where(array)
where 函数会返回所有非零元素的索引。
a = np.array([1, 2, 4, 6])
a > 2 # [False False True True]
b = np.where(a > 2)
b # 返回的是索引位置
# 注意到 where 的返回值是一个元组。
index = np.where(a > 2)[0]
print(index) # [2 3]
# 可以直接用 where 的返回值进行索引:
loc = np.where(a > 2)
b = a[loc]
print(b) # [4 6]
考虑二维数组:
a = np.array([[0, 12, 5, 20],
[1, 2, 11, 15]])
loc = np.where(a > 10)
print(loc) # (array([0, 0, 1, 1]), array([1, 3, 2, 3]))
# 也可以直接用来索引a:
b = a[loc]
print(b) # [12 20 11 15]
或者可以这样:
rows, cols = np.where(a > 10)
print(rows)
print(cols)
print(a[rows, cols])
例子:
a = np.arange(20)
a.shape = 5, 4
a
a > 12
b = np.where(a > 12)
b
# (array([3, 3, 3, 4, 4, 4, 4]), array([1, 2, 3, 0, 1, 2, 3]))
a[b] # [13 14 15 16 17 18 19]
Numpy方法
Numpy的常用方法。
import numpy as np
a = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])
a
for row in a:
print(row)
所有元素的 迭代器:
for i in a.flat:
print(i)
矩阵转置
print(a)
print(a.T)
print(a)
print(a.shape) # 数组形状 (m,n,o,...)
print(a.size) # 数组元素数
a.resize((4, 2))
print(a)
print(a.shape)
squeeze
把shape为1的维度去掉:
a = np.arange(10).reshape(1,10)
a
a.shape
b = np.squeeze(a)
b
b.shape
再举个多维的例子:
a = np.arange(10).reshape(1, 2, 5)
print(a)
print(a.shape)
b = np.squeeze(a)
b.shape
a.shape
复制
a = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])
b = a.copy()
b[0][0] = -1
b