In [ ]:
Python数据分析第三天 - NumPy详解2
In [31]:
# %load hello.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'].insert(0, 'SimHei')
plt.rcParams['axes.unicode_minus'] = False
#config InlineBackend.figure_format = 'svg'
In [4]:
#广播机制
1. 两个数组后缘维度(数组对象的shape属性从后向前看对应的部分)相同,可以触发广播机制。
2. 两个数组后缘维度不相同,但是不相同的部分其中一方为1,也可以触发广播机制。
In [9]:
array1 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
array2 = np.array([1, 2, 3])
array3 = np.array([[1],[2],[3],[4]])
In [10]:
array1 + array2
Out[10]:
array([[1, 2, 3],
       [2, 3, 4],
       [3, 4, 5],
       [4, 5, 6]])
In [11]:
array1 +array3
Out[11]:
array([[1, 1, 1],
       [3, 3, 3],
       [5, 5, 5],
       [7, 7, 7]])
In [7]:
array4 = np.random.randint(1,100,(3,1))
array5 = np.random.randint(1,100,(1,3))
In [12]:
array4
Out[12]:
array([[71],
       [ 6],
       [30]], dtype=int32)
In [13]:
array5
Out[13]:
array([[80, 23, 86]], dtype=int32)
In [8]:
array4 + array5
Out[8]:
array([[151,  94, 157],
       [ 86,  29,  92],
       [110,  53, 116]], dtype=int32)
In [ ]:
#通⽤⼀元函数

函数 说明 abs / fabs 求绝对值的函数 sqrt 求平⽅根的函数,相当于 array ** 0.5 square 求平⽅的函数,相当于 array ** 2 exp 计算 的函数 相当于 np.e ** array log / log10 / log2 对数函数( e 为底 / 10 为底 / 2 为底) sign 符号函数( 1 - 正数; 0 - 零; -1 - 负数) ceil / floor 上取整 / 下取整 isnan 返回布尔数组,NaN对应 True ,⾮NaN对应 False isfinite / isinf 判断数值是否为⽆穷⼤的函数 cos / cosh / sin 三⻆函数 sinh / tan / tanh 三⻆函数 arccos / arccosh / arcsin 反三⻆函数 arcsinh / arctan / arctanh 反三⻆函数 rint / round 四舍五⼊函数

In [15]:
array6 = np.array([1,2,3,np.nan,4,5,np.inf,6,-np.inf])
In [18]:
array6[~np.isnan(array6)]
Out[18]:
array([  1.,   2.,   3.,   4.,   5.,  inf,   6., -inf])
In [19]:
array6[~np.isinf(array6)]
Out[19]:
array([ 1.,  2.,  3., nan,  4.,  5.,  6.])
In [21]:
array6[~np.isnan(array6) & ~np.isinf(array6)]
Out[21]:
array([1., 2., 3., 4., 5., 6.])
In [24]:
x = np.linspace(0.1,9.9,120)
y1 = np.sin(x)
y2 = np.log(x)
y3 = np.log10(x)
In [33]:
plt.plot(x,y1)
plt.plot(x,y2)
plt.plot(x,y3)
#plt.legend()
plt.show()
No description has been provided for this image
In [ ]:
#面试官:普通函数如何使其像NumPy的函数一样进行矢量化操作
#答:numpy中有一个vectorize的函数可以对普通函数进行矢量化处理,他是一个装饰器函数。

#面试官:什么是装饰器?
# 答:用一个函数去装饰另外一个函数或类,并为其提供额外的功能。
In [35]:
import random
import time

# 装饰器函数的参数也是一个函数,它代表了被装饰的函数
# 装饰器函数的返回值也是一个函数,它代表了带有装饰功能的函数
def record_time(func):

    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f'消耗时间: {end - start:.3f}秒')
        return result

    return wrapper


@record_time
def download(filename):
    """下载文件"""
    print(f'开始下载{filename}.')
    time.sleep(2 + random.random() * 5)
    print(f'{filename}下载完成.')


@record_time
def upload(filename):
    """上传文件"""
    print(f'开始上传{filename}.')
    time.sleep(3 + random.random() * 6)
    print(f'{filename}上传完成.')


# download = record_time(download)
# upload = record_time(upload)
download('MySQL从删库到跑路.avi')
upload('Python从入门到住院.pdf')
开始下载MySQL从删库到跑路.avi.
MySQL从删库到跑路.avi下载完成.
消耗时间: 6.043秒
开始上传Python从入门到住院.pdf.
Python从入门到住院.pdf上传完成.
消耗时间: 6.707秒
In [57]:
#递归调用
from math import factorial as fac
@np.vectorize
def fac(n):
    if n == 0 :return 1
    return n * fac(n-1)
fac(5)
Out[57]:
array(120)
In [ ]:
from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n):
    if n in {1,2}:return 1
    return fib(n-1) + fib(n-2)

for x in range(1,21):
    print(x,fib(x))
In [58]:
array7 = np.arange(1,10)
#fac = np.vectorize(fac)
fac(array7)
Out[58]:
array([     1,      2,      6,     24,    120,    720,   5040,  40320,
       362880])
In [59]:
#通⽤⼆元函数

函数 说明 add(x, y) / substract(x, y) 加法函数 / 减法函数 multiply(x, y) / divide(x, y) 乘法函数 / 除法函数 floor_divide(x,y) / mod(x, y) 整除函数 / 求模函数 allclose(x, y) 检查数组 x 和 y 元素是否⼏乎相等 power(x, y) 数组x的元素 和数组 的元素 ,计算 maximum(x, y) /fmax(x, y) 两两⽐较元素获取最⼤值 / 获取最⼤值(忽略NaN) minimum(x, y) /fmin(x, y) 两两⽐较元素获取最⼩值 / 获取最⼩值(忽略NaN) dot(x, y) 点积运算(数量积,通常记为 ,⽤于欧⼏⾥得空间(Euclidean space)) inner(x, y) 内积运算(内积的含义要⾼于点积,点积相当于是内积在欧⼏⾥得空间 的特例,⽽ 内积可以推⼴到赋范向量空间,只要它满⾜平⾏四边形法则即可) cross(x, y) 叉积运算(向量积,通常记为 ,运算结果是⼀个向量) outer(x, y) 外积运算(张量积,通常记为 ,运算结果通常是⼀个矩阵) intersect1d(x,y)计算 x 和 y 的交集,返回这些元素构成的有序数组 union1d(x, y) 计算 x 和 y 的并集,返回这些元素构成的有序数组 in1d(x, y) 返回由判断 x 的元素是否在 y 中得到的布尔值构成的数组 setdiff1d(x, y) 计算 x 和 y 的差集,返回这些元素构成的数组 setxor1d(x, y) 计算 x 和 y 的对称差,返回这些元素构成的数组

In [ ]:
#NumPy其他函数

函数 说明 unique 去除数组重复元素,返回唯⼀元素构成的有序数组 copy 返回拷⻉数组得到的数组 sort 返回数组元素排序后的拷⻉ split / hsplit / vsplit 将数组拆成若⼲个⼦数组 stack / hstack / vstack 将多个数组堆叠成新数组 concatenate 沿着指定的轴连接多个数组构成新数组 append / insert 向数组末尾追加元素 / 在数组指定位置插⼊元素 argwhere 找出数组中⾮0元素的位置 extract / select / where 按照指定的条件从数组中抽取或处理数组元素 flip 沿指定的轴翻转数组中的元素 fromregex 通过读取⽂件和正则表达式解析获取数据创建数组对象 repeat / tile 通过对元素的重复来创建新数组 roll 沿指定轴对数组元素进⾏移位 resize 重新调整数组的⼤⼩ place / put 将数组中满⾜条件的元素/指定的元素替换为指定的值 partition ⽤选定的元素对数组进⾏⼀次划分并返回划分后的数组

In [61]:
temp = np.random.randint(1,10,50)
temp
Out[61]:
array([9, 2, 9, 2, 4, 9, 2, 9, 5, 8, 7, 3, 1, 5, 7, 9, 1, 9, 6, 5, 1, 1,
       6, 4, 2, 7, 6, 3, 8, 9, 2, 3, 6, 9, 1, 1, 1, 8, 7, 8, 1, 1, 2, 8,
       9, 1, 2, 5, 2, 5], dtype=int32)
In [62]:
np.unique(temp)
Out[62]:
array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
In [76]:
#堆叠
In [65]:
array8 = np.array([[1,1,1],[2,2,2],[3,3,3]])
array9 = np.array([[4,4,4],[5,5,5],[6,6,6]])
In [67]:
np.hstack((array8,array9))
Out[67]:
array([[1, 1, 1, 4, 4, 4],
       [2, 2, 2, 5, 5, 5],
       [3, 3, 3, 6, 6, 6]])
In [68]:
np.vstack((array8,array9))
Out[68]:
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3],
       [4, 4, 4],
       [5, 5, 5],
       [6, 6, 6]])
In [69]:
np.stack((array8,array9))
Out[69]:
array([[[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]],

       [[4, 4, 4],
        [5, 5, 5],
        [6, 6, 6]]])
In [75]:
#拆分
In [70]:
temp4 = np.hstack((array8,array9))
In [72]:
np.hsplit(temp4,3)
Out[72]:
[array([[1, 1],
        [2, 2],
        [3, 3]]),
 array([[1, 4],
        [2, 5],
        [3, 6]]),
 array([[4, 4],
        [5, 5],
        [6, 6]])]
In [73]:
temp5 = np.vstack((array8,array9))
In [79]:
np.vsplit(temp5,3)
Out[79]:
[array([[1, 1, 1],
        [2, 2, 2]]),
 array([[3, 3, 3],
        [4, 4, 4]]),
 array([[5, 5, 5],
        [6, 6, 6]])]
In [78]:
temp6 = np.random.randint(10,100,9)
temp6
Out[78]:
array([91, 95, 78, 30, 19, 41, 63, 21, 93], dtype=int32)
In [85]:
np.append(temp6,[999,888])
Out[85]:
array([ 91,  95,  78,  30,  19,  41,  63,  21,  93, 999, 888])
In [84]:
np.insert(temp6,2,[999,888])
Out[84]:
array([ 91,  95, 999, 888,  78,  30,  19,  41,  63,  21,  93], dtype=int32)
In [83]:
np.insert(temp6,[2,-1],[999,888])
Out[83]:
array([ 91,  95, 999,  78,  30,  19,  41,  63,  21, 888,  93], dtype=int32)
In [ ]:
#按条件抽取元素(相当于布尔索引)
In [86]:
#按条件抽取元素
np.extract(temp6 > 60 ,temp6)
Out[86]:
array([91, 95, 78, 63, 93], dtype=int32)
In [ ]:
temp6
In [87]:
#根据多组条件分别对元素进行对应的处理
np.select([temp6<40,temp6>70],[temp6*2,temp6//2],50)  #([条件1,条件2],[事件1,事件2],else的结果)
Out[87]:
array([45, 47, 39, 60, 38,  0,  0, 42, 46], dtype=int32)
In [89]:
#对满足和不满足的条件分别处理元素
np.where(temp6 < 50 , temp6 *10 , temp6 // 10)  # 条件 ,满足,不满足 
Out[89]:
array([  9,   9,   7, 300, 190, 410,   6, 210,   9], dtype=int32)
In [93]:
temp7 = np.roll(temp6,-1)
temp7
Out[93]:
array([95, 78, 30, 19, 41, 63, 21, 93, 91], dtype=int32)
In [94]:
temp6
Out[94]:
array([91, 95, 78, 30, 19, 41, 63, 21, 93], dtype=int32)
In [97]:
np.resize(temp6,(4,4))  # 改变数组的大小,拿源数据依次填充直到填满
Out[97]:
array([[91, 95, 78, 30],
       [19, 41, 63, 21],
       [93, 91, 95, 78],
       [30, 19, 41, 63]], dtype=int32)
In [98]:
np.put(temp6,[3,4],[999,888]) #根据索引 直接修改源数据
In [99]:
temp6  
Out[99]:
array([ 91,  95,  78, 999, 888,  41,  63,  21,  93], dtype=int32)
In [100]:
np.place(temp6, temp6 == 999,30)
np.place(temp6, temp6 == 888,19)   #将刚才替换的999 888 改回原来的值
In [101]:
temp6
Out[101]:
array([91, 95, 78, 30, 19, 41, 63, 21, 93], dtype=int32)
In [ ]:
guido = plt.imread('wenjian/py.jpg')
guido
In [ ]:
a, b, c = np.vsplit(guido[:480,:480],3)
a,b,c
In [111]:
guido_parts = np.array([np.hsplit(a,3),np.hsplit(b,3),np.hsplit(c,3)])
guido_parts.shape
Out[111]:
(3, 3, 160, 160, 3)
In [115]:
plt.figure(figsize=(6,6))
plt.subplots_adjust(wspace=0.05,hspace=0.05)
for i in range(3):
    for j in range(3):
        plt.subplot(3,3,i*3+j+1)
        plt.imshow(guido_parts[i,j])
        plt.axis('off')
plt.show()
No description has been provided for this image
In [116]:
obama = plt.imread('wenjian/obama.jpg')
obama.shape
Out[116]:
(750, 500, 3)
In [119]:
temp8 = (guido * 0.3 + obama * 0.7).astype('u1')
plt.imshow(temp8)
Out[119]:
<matplotlib.image.AxesImage at 0x2be169f3a10>
No description has been provided for this image
In [ ]:
#向量和行列式
In [120]:
u = np.array([5,1,3])
m1 = np.array([4,5,1])
m2 = np.array([5,1,5])
In [121]:
np.dot(u,m1) / (np.linalg.norm(u) * np.linalg.norm(m1))
Out[121]:
np.float64(0.7302967433402215)
In [122]:
np.dot(u,m2) / (np.linalg.norm(u) * np.linalg.norm(m2))
Out[122]:
np.float64(0.9704311900788593)
In [125]:
np.rad2deg(np.arccos(0.7302967433402215))
Out[125]:
np.float64(43.08872313536282)
In [126]:
np.rad2deg(np.arccos(0.9704311900788593))
Out[126]:
np.float64(13.967881205170064)
In [129]:
temp9 = np.random.randint(10,100,(3,3))
temp9
Out[129]:
array([[16, 15, 90],
       [68, 87, 86],
       [79, 27, 32]], dtype=int32)
In [130]:
#行列式
np.linalg.det(temp9).round(0)
Out[130]:
np.float64(-376668.0)
In [131]:
#矩阵
In [132]:
m1 = np.array([[1,0,2],[-1,3,1]])
In [134]:
m2 = np.array([[3,1],[2,1],[1,0]])
In [136]:
#矩阵乘法
m1 @ m2
Out[136]:
array([[5, 1],
       [4, 2]])
In [138]:
#矩阵乘法
m3 = np.matmul(m1,m2)
m3
Out[138]:
array([[5, 1],
       [4, 2]])
In [139]:
#转置
m3.T
Out[139]:
array([[5, 4],
       [1, 2]])
In [140]:
#逆矩阵
m4 = np.linalg.inv(m3)
m4
Out[140]:
array([[ 0.33333333, -0.16666667],
       [-0.66666667,  0.83333333]])
In [141]:
m3 @ m4
Out[141]:
array([[ 1.00000000e+00, -1.11022302e-16],
       [ 0.00000000e+00,  1.00000000e+00]])
In [142]:
np.allclose(m3 @ m4 ,np.eye(2))
Out[142]:
True
In [143]:
A = np.array([[1,2,1],[3,7,2],[2,2,1]])
B = np.array([8,23,9]).reshape(-1,1)
In [144]:
np.linalg.matrix_rank(A)
Out[144]:
np.int64(3)
In [145]:
np.linalg.matrix_rank(np.hstack((A,B)))
Out[145]:
np.int64(3)
In [146]:
np.linalg.inv(A) @ B
Out[146]:
array([[1.],
       [2.],
       [3.]])
In [147]:
np.linalg.solve(A,B)
Out[147]:
array([[1.],
       [2.],
       [3.]])
In [156]:
from scipy.ndimage import zoom,rotate,sobel
In [153]:
temp11 = zoom(guido,(0.5,1.5,1))
In [154]:
plt.imshow(temp11)
Out[154]:
<matplotlib.image.AxesImage at 0x2be350e49e0>
No description has been provided for this image
In [155]:
temp12 = rotate(guido,30)
plt.imshow(temp12)
Out[155]:
<matplotlib.image.AxesImage at 0x2be35082f60>
No description has been provided for this image
In [157]:
plt.imshow(sobel(guido))   #通过颜色对比物体边缘
Out[157]:
<matplotlib.image.AxesImage at 0x2be3552aa50>
No description has been provided for this image
In [ ]:
函数    说明
diag  以⼀维数组的形式返回⽅阵的对⻆线元素或将⼀维数组转换为⽅阵(⾮对⻆元素元素为0)
matmul  矩阵乘法运算
trace 计算对⻆线元素的和
norm 求矩阵或向量的范数
det 计算⾏列式的值
matrix_rank 计算矩阵的秩
eig 计算矩阵的特征值(eigenvalue)和特征向量(eigenvector)
inv 计算⾮奇异矩阵( 阶⽅阵)的逆矩阵
pinv 计算矩阵的摩尔-彭若斯(Moore-Penrose)⼴义逆
qr QR分解(把矩阵分解成⼀个正交矩阵与⼀个上三⻆矩阵的积)
svd 计算奇异值分解(singular value decomposition)
solve 解线性⽅程组 ,其中 是⼀个⽅阵
lstsq 计算 的最⼩⼆乘解
In [ ]:
#多项式
In [158]:
p1 = np.poly1d([3, 2, 1])
p2 = np.poly1d([1, 2, 3])
print(p1)
print(p2)
   2
3 x + 2 x + 1
   2
1 x + 2 x + 3
In [159]:
print(p1 + p2)
   2
4 x + 4 x + 4
In [160]:
print(p1 * p2)
   4     3      2
3 x + 8 x + 14 x + 8 x + 3
In [161]:
print(p1.deriv())
 
6 x + 2
In [162]:
print(p1.integ())
   3     2
1 x + 1 x + 1 x
In [163]:
print(p1.integ().deriv())
   2
3 x + 2 x + 1
In [164]:
from numpy.polynomial import Polynomial
In [166]:
p1 = Polynomial([1,2,3])
p1
Out[166]:
$x \mapsto \text{1.0} + \text{2.0}\,x + \text{3.0}\,x^{2}$
In [167]:
p2 = Polynomial([3,2,1])
p2
Out[167]:
$x \mapsto \text{3.0} + \text{2.0}\,x + \text{1.0}\,x^{2}$
In [168]:
p1 * p2
Out[168]:
$x \mapsto \text{3.0} + \text{8.0}\,x + \text{14.0}\,x^{2} + \text{8.0}\,x^{3} + \text{3.0}\,x^{4}$
In [169]:
(p1*p2).deriv()
Out[169]:
$x \mapsto \text{8.0} + \text{28.0}\,x + \text{24.0}\,x^{2} + \text{12.0}\,x^{3}$
In [171]:
x = np.array([
 25000, 15850, 15500, 20500, 22000, 20010, 26050, 12500, 18500, 27300,
 15000, 8300, 23320, 5250, 5800, 9100, 4800, 16000, 28500, 32000,
 31300, 10800, 6750, 6020, 13300, 30020, 3200, 17300, 8835, 3500
])
y = np.array([
 2599, 1400, 1120, 2560, 1900, 1200, 2320, 800, 1650, 2200,
 980, 580, 1885, 600, 400, 800, 420, 1380, 1980, 3999,
 3800, 725, 520, 420, 1200, 4020, 350, 1500, 560, 500
])
In [ ]:
#计算相关系数
In [172]:
np.corrcoef(x,y)
Out[172]:
array([[1.        , 0.92275889],
       [0.92275889, 1.        ]])
In [174]:
plt.scatter(x,y)
plt.show()
No description has been provided for this image
In [187]:
a,b =np.polyfit(x,y,deg=1)
a,b
Out[187]:
(np.float64(0.1103337164602619), np.float64(-294.8834372455541))
In [181]:
x1 = np.linspace(0,35000,120)
y1 = a * x1 + b
In [189]:
plt.scatter(x,y)
plt.plot(x1,y1,color='r',linewidth=4)
plt.show()
No description has been provided for this image
In [ ]: