NumPy的使用

数据分析 2019-03-24 5917 字 1237 浏览 点赞

前言

为什么在 Python 已有 list 基础类型的状况下,还要用 NumPy 处理数据?

关于 NumPy 的优势有以下几点:

  1. 列表 list 的元素在系统内存中分散存储,NumPy 数组存储在一个均匀连续的内存块中;
  2. 缓存会直接把字节块从 RAM 加载到 CPU 寄存器中;
  3. NumPy中的矩阵计算可以采用多线程方式,充分利用多核 CPU 计算资源。

如果对上述内容用一个字做总结,那就是:NumPy ,

NumPy中的两个重要对象:ndarray(解决多维数组问题),ufunc(对数组进行处理的函数)。

ndarray

创建数组

方法:array()

import numpy as np

# 创建一个一维数组
arrOne = np.array([1, 2, 3, 4])

# 创建一个三维数组
arrTwo = np.array([[1, "x", 3], [2, 3, 5], [3, "y", "z"]])

print(arrOne)  # 输出:[1 2 3 4]
print(arrTwo)  # 输出:[['1' 'x' '3']
               #       ['2' '3' '5']
               #       ['3' 'y' 'z']]

需要注意打印arrTwo的结果,当元素中存在str类型时,int型会被转换成str型。符合“一个数组中只能存放相同类型的元素”这个概念。

创建连续数据的数组

方法:arange()linspace()

arrOne = np.arange(10, 50, 10)
print(arrOne)  # 输出:[10 20 30 40]

arrTwo = np.linspace(10, 40, 4)
print(arrTwo)  # 输出:[ 10.  20.  30.  40.]
  • arange()的使用类似range(),即三个参数分别是:初始值,终值,步长(不包含终值)
  • linspace()则表示线性等分向量,三个参数分别是:初始值,终值,元素个数(包含终值)。也就是说,linspace()的作用是在[初始值, 终值]这个区间范围内,等分出n个元素。

创建结构体数组

方法:dtype()array()。(感觉还是C语言实现更自然,也许是用习惯之故)

# 可以认为是在创建一个结构体,在C语言中类似这样:
# typedef struct {
#      char* name;
#      int id;
#     int age;
#     float score;
# } structType;
structType = np.dtype({"names": ["name", "id", "age", "score"],
                       "formats": ["S10", "i", "i", "f"]})

# 利用 structType 结构创建结构体数据,并初始化值
students = np.array([("lily", 10271122, 18, 468.5),
                    ("bobby", 10271123, 18, 521.0),
                    ("joe", 10271124, 19, 472.5)], dtype=structType)

print(students)  # 输出:[(b'lily', 10271122, 18, 468.5) 
                 #         (b'bobby', 10271123, 18, 521.0)
                 #         (b'joe', 10271124, 19, 472.5)]

创建结构体数组的时候,每个完整的结构体是一个元组类型,这样做主要是为了跟多维数组区分。

访问元素

  • 普通数组:普通数组通过下标访问即可,也可以切片的方式
arrayCommon = np.array(["z", "t", "y"])
print(arrayCommon[2])  # 输出:y
print(arrayCommon[1:])  # 输出:['t' 'y']

arrayTwoDimen = np.array([[512, 1024], ["zty", "dkh"]])
print(arrayTwoDimen[1][0])  # 输出:zty
  • 结构体数组:结构体数组则需要搭配关键字来访问元素(拿前边的 students 作为示例)
print(students[1])  # 输出:(b'bobby', 10271123, 18, 521.0)

print(students[1]["name"])  # 输出:b'bobby'

# 获取所有人的成绩
print(students[:]["score"])  # 输出:[ 468.5  521.   472.5]

rank、axes、axis

秩与轴是 NumPy 中一个重要概念。在 NumPy 数组中,维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。而每一个线性的数组称为一个轴(axes),其实秩就是描述轴的数量

axis 是 ufunc 中的一个重要参数,有了它可以更灵活的使用 ufunc。关于它的解释知乎上有一文说得通俗易懂,推荐去看:Python · numpy · axis

ufunc 运算

算术运算

方法:add()subtract()multiply()divide()power()remainder()mod()

arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([1, 2, 3, 4])

print(np.add(arr1, arr2))  # 对应元素相加  # 输出:[2 4 6 8]

print(np.subtract(arr1, arr2))  # 对应元素相减  # 输出:[0 0 0 0]

print(np.multiply(arr1, arr2))  # 对应元素相乘  # 输出:[ 1  4  9 16]

print(np.divide(arr1, arr2))  # 对应元素相除  # 输出:[ 1.  1.  1.  1.]

print(np.power(arr1, arr2))
# 右边数组中的元素 作为 左边数组中元素的次方  # 输出:[  1   4  27 256]

print(np.remainder(arr1, arr2))
# 左边元素对右边元素取余,也可以用np.mod(),结果一样  # 输出:[0 0 0 0]

计算最大最小

方法:amax()amin()

arr1 = np.array([1, 4, 3, 2])

print(np.amax(arr1))  # 数组中最大值  # 输出:4
print(np.amin(arr1))  # 数组中最小值  # 输出:1

arr2 = np.array([
        [1, 2, 10, 1],
        [3, 11, 1, 2],
    ])

print(np.amax(arr2))  # 输出:11

print(np.amax(arr2, 0))  # 输出:[ 3 11 10  2]
# axis = 0, 将[1, 3] [2, 11] [10, 1] [1, 2] 看作4个元素

print(np.amax(arr2, 1))  # 输出:[10 11]
# axis = 1, 将[1, 2, 10, 1] [3, 11, 1, 2] 看作2个元素

统计最大最小值的差

方法:ptp()

arr1 = np.array([1, 4, 3, 2])

arr2 = np.array([
        [1, 2, 10, 1],
        [3, 11, 1, 2],
    ])

print(np.ptp(arr1))  # 输出:3

print(np.ptp(arr2))  # 输出:10
print(np.ptp(arr2, 0))  # 输出:[2 9 9 1]
print(np.ptp(arr2, 1))  # 输出:[ 9 10]

统计数组的百分位数

方法:percentile()

arr1 = np.array([1, 4, 3, 2])

print(np.percentile(arr1, 20))  # 输出:1.6

公式:$(最大 - 最小)* 占比 + 最小 $ 。这里的占比是20%。

中位数与平均数

方法:median()mean()

arr1 = np.array([1, 4, 3, 2])

arr2 = np.array([
        [1, 2, 10, 1],
        [3, 11, 1, 2],
    ])

print(np.median(arr1))  # 输出: 2.5
print(np.median(arr2, 0))  # 输出:[ 2.   6.5  5.5  1.5]

# 说明
mean()表示平均数,用法与median()相似

加权平均值

方法:average()

arr1 = np.array([1, 2, 3, 4])
wts = [1, 2, 3, 4]  # 迭代类型即可

print(np.average(arr1, weights=wts))  # 输出:3.0

# 为每个元素设置权重,如果不设置,默认每个元素的权重相同
print(np.average(arr1))  # 输出:2.5

方差与标准差

var(),std()

arr1 = np.array([1, 2, 3, 4])
print(np.std(arr1))  # 输出:1.11803398875
print(np.var(arr1))  # 输出:1.25

方差公式:$((x1 - avg)^2 + (x2 - avg)^2 + (x3 - avg)^2 + ...) / n$

NumPy 排序

sort() 函数,sort(a, axis=-1, kind=‘quicksort’, order=None),默认情况下使用快速排序:

  • kind,可指定排序类型: quicksort、mergesort、heapsort 分别表示快速排序、合并排序、堆排序;
  • axis 默认 -1,即沿着数组的最后一个轴进行排序,也可以取不同的 axis 轴,或者 axis=None 代表采用扁平化的方式作为一个向量进行排序;
  • order 字段,对于结构化的数组可以指定按照某个字段进行排序。
arr2 = np.array([
        [1, 11, 9],
        [2, 1, 5],
        [5, 1, 1],
    ])

print(np.sort(arr2, axis=None))  # 全部元素参与排序
# 输出:[ 1  1  1  1  2  5  5  9 11]

print(np.sort(arr2, axis=-1))  # 沿数组最后一个轴排序
# 输出:
# [[ 1  9 11]
#  [ 1  2  5]
#  [ 1  1  5]]

print(np.sort(arr2, axis=0))
# 输出:
# [[ 1  1  1]
#  [ 2  1  5]
#  [ 5 11  9]]

print(np.sort(arr2, axis=1))
# 输出:
# [[ 1  9 11]
#  [ 1  2  5]
#  [ 1  1  5]]

由于上述二维数组 axis 最大 = 1,因此 axis = 1与 axis = -1 具有相同效果。

总结

感谢



本文由 Guan 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论