跳转至

numpy

性能对比

import numpy as np

# 实现列表每个元素的平方和立方加和

# 普通python代码
def python_sum(n):
    return [(i ** 2 + i ** 3) for i in range(n)]


# numpy 实现
def numpy_sum(n):
    return np.arange(n) ** 2 + np.arange(n) ** 3


# 统计执行耗时
# %timeit python_sum(10000)
# %timeit numpy_sum(10000)

# 大数据量测试
# %timeit python_sum(1000 * 10000) => 1m17.3s
# %timeit numpy_sum(1000 * 10000)  => 3.6s


array对象以及创建array的方法

"""
array 对象的背景

    - Numpy的核心数据结构,就叫做array(数组),array对象可以是一维数组,也可以是多维数组
    - Python的List也可以实现相同功能,但是array比List的优点在于:性能好,包含数组元数据信息,大量的便捷函数
    - Numpy成为事实上的Scipy,Pandas,Scikit-Learn,Tensorflow,PaddlePaddle等框架的通用底层语言
    - Numpy与Python List的一个不同点是,它的元素必须是同一种数据类型,这也是Numpy高性能的一个原因

"""

import numpy as np

# 创建一维数组
x1 = np.array([1, 2, 3, 4, 5, 6, 7, 8])

# 创建二维数组
x2 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])


# array对象的属性
x2.shape
x2.ndim
x2.size
x2.dtype


# 使用 arange 创建数字序列
np.arange(10)  # => array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) => 设置结束数值
np.arange(2, 10)  # => array([2, 3, 4, 5, 6, 7, 8, 9]) => 设置起始和结束数值
np.arange(2, 10, 2)  # => array([2, 4, 6, 8]) => 设置起始和结束数值,且设置步长


# 使用 ones 创建全是1的数组
np.ones(10)  # => array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.ones((2, 3))  # => array([[1., 1., 1.], [1., 1., 1.]]) => 2行3列

# 使用ones_like创建形状相同的数组
np.ones_like(x2)  # => array([[1, 1, 1, 1], [1, 1, 1, 1]])


# 使用 zeros 创建全是1的数组
np.zeros(10)  # => array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((2, 3))  # => array([[0., 0., 0.], [0., 0., 0.]]) => 2行3列

# 使用ones_like创建形状相同的数组
np.zeros_like(x2)  # => array([[0, 0, 0, 0], [0, 0, 0, 0]])


# 使用 empty 创建全是0的数组
np.empty(10)  # => array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.empty((2, 3))  # => array([[0., 0., 0.], [0., 0., 0.]]) => 2行3列

# 使用ones_like创建形状相同的数组
np.empty_like(x2)  # => array([[0, 0, 0, 0], [0, 0, 0, 0]])


# 使用 full 创建全指定值的数组 => np.full(shape, fill_vaue, dtype=None, order="C")
np.full(10, 666)  # => array([666, 666, 666, 666, 666, 666, 666, 666, 666, 666])
np.full((2, 3), 666)  # => array([[666, 666, 666], [666, 666, 666]]) => 2行3列

# 使用ones_like创建形状相同的数组
np.full_like(x2, 666)  # => array([[666, 666, 666, 666], [666, 666, 666, 666]])


# 使用 random 模块生成随机数的数组 => randn(d0, d1, ..., dn)
np.random.randn()  # => -1.7396446526555316
# 一维数组
np.random.randn(3)  # => array([-0.49077112,  1.32385458, -0.74204074])
# 二维数组
np.random.randn(3, 2)  # => array([[-0.41556608, -1.44517028],[ 0.94246819,  2.3243538 ],[-0.48885273, -0.92321349]])

# 三维数组
np.random.randn(3, 2, 4)

"""
array([[[ 0.72067021, -1.07090792, -0.05211906,  0.20735259],
        [-0.89798276,  0.8301943 ,  0.44650108, -0.86517441]],

       [[ 0.46013563,  0.55681986, -0.26365684, -1.04471932],
        [-1.20813438,  0.69417912,  0.4398812 , -0.79399575]],

       [[-1.15638636, -0.41220997, -0.25808663, -0.42699029],
        [ 1.62206012, -1.64449513, -0.15701649, -1.34369567]]])
"""


array 操作

import numpy as np


# 将一维数组变成二维数组
A = np.arange(10).reshape(2, 5)  # => array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])

# 元素加和 - 广播加和 - 自动对每一个元素加和
A + 1  # => array([[ 1,  2,  3,  4,  5], [ 6,  7,  8,  9, 10]])

A * 3  # => array([[ 0,  3,  6,  9, 12], [15, 18, 21, 24, 27]])

np.sin(A)
# => array([[ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 ], [-0.95892427, -0.2794155 ,  0.6569866 ,  0.98935825,  0.41211849]])


B = np.random.randn(2, 5)

# 数组求和/求差 => 对应元素进行求和/求差
A + B
A - B


查询

import numpy as np


# 一维数组
x1 = np.arange(10)
# 二维数组
x2 = np.arange(20).reshape(4, 5)


# 基础索引

# 一维数组
print(x1[0], x1[1], x1[-1])  # => 0 1 9
print(x1[2:4])  # => [2 3]
print(x1[2:-1])  # => [2 3 4 5 6 7 8]
print(x1[2:])  # => [2 3 4 5 6 7 8 9]
print(x1[:-2])  # => [0 1 2 3 4 5 6 7]


x2[0, 0]  # 等价于 x2[0][0] => 0
x2[-1, 2]  # => 17
x2[2]  # => array([10, 11, 12, 13, 14])
x2[:-1]  # array([[ 0,  1,  2,  3,  4], [ 5,  6,  7,  8,  9], [10, 11, 12, 13, 14]])
x2[0:2, 2:4]  # array([[2, 3], [7, 8]])
x2[:, 2]  # => array([ 2,  7, 12, 17])


数组

x2[2:4]
x2[2:4] = 666
# => array([[  0,   1,   2,   3,   4], [  5,   6,   7,   8,   9], [666, 666, 666, 666, 666], [666, 666, 666, 666, 666]])


# 神奇索引:用整数数组进行的索引

# 一维数组
x1 = np.arange(10)

x1[[3, 4, 7]]  # => array([3, 4, 7])

indexs = np.array([[0, 2], [1, 3]])
x1[indexs]  # => array([[0, 2], [1, 3]])


# 示例:获取数组中最大的前N个数字

arr = np.random.randint(1, 100, 10)
arr

# argsort() 会返回排序后的索引 index
index = arr.argsort()[-3:]
arr[index]


# 二维数组

x2 = np.arange(20).reshape(4, 5)
x2

# 筛选多行,列可以省略
x2[[0, 2]]
x2[[0, 2], :]

# 筛选多列,行不能省略
x2[:, [0, 2, 3]]

# 同时指定行列
x2[[0, 2, 3], [1, 3, 4]]


# 布尔索引

# 一维数组
x1 = np.arange(10)
x1  # => array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

x1 > 5  # => array([False, False, False, False, False, False,  True,  True,  True, True])
x1[x1 > 5]  # => array([6, 7, 8, 9])


# 实例:按条件赋值
x1[x1 <= 5] = 0
x1[x1 > 5] = 1

# => array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1])


# 二维数组

x2 = np.arange(20).reshape(4, 5)
x2

x2 > 5
x2[x2 > 5]


x2[:, 3]

x2[x2[:, 3] > 5]

x2[(x2 % 2 == 0) & (x2 > 7)]  # array([ 8, 10, 12, 14, 16, 18])
x2[(x2 % 2 == 0) | (x2 > 7)]  # array([ 0,  2,  4,  6,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])