NumPy 基础(数组与向量化计算)——《利用Python进行数据分析》第四章阅读笔记

NumPy 基础(数组与向量化计算)——《利用Python进行数据分析》第四章阅读笔记

前言

上一次总结了该书第三章的内容,这次带来第四章,也就是NumPy 的基础部分,有关Numpy的历史发展等相关知识点,读者可直接参考该书的87、88页。从这两页,我们知道Numpy主要是在数组部分,其算法库是采用C编写,数据存储在连续内存块上,这一特性,使得Numpy数组方法在性能上要远优于传统的Python方法。
环境依旧是 Pycharm 2020.2.4 社区版, Anconda3

一 NumPy ndarray: 多维数组对象

作为NumPy的核心特征之一,ndarray即N维数组对象,是Python中一个快速、灵活的大型数据集容器。

用下面的随机NumPy数组代码,来感受一下

import numpy as np

data = np.random.randn(2, 3)
print(data)

print(data * 10)
print(data + data)

print(data.shape)

print(data.dtype)

1. 生成 ndarray

几个示例代码可以参考一下

import numpy as np

data1 = [6, 7.5, 8, 0, 1]

arr1 = np.array(data1)
print(arr1, arr1.dtype)

data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
print(arr2, arr2.dtype)

print(arr2.ndim, arr1.ndim)
print(arr2.shape)

print(np.zeros((3, 6)))

print(np.empty((2, 3, 2)))

print(np.arange(12))

更多的数组生成函数可以参考该书的 表4-1

2. ndarray 的数据类型

数据类型,即dtype,是一个特殊对象,它包含了ndarray 需要为某一种类型数据申明的内存块信息(也称为元数据,即表示数据的数据)

import numpy as np

arr1 = np.array([1, 2, 3], dtype=np.float64)
arr2 = np.array([1, 2, 3], dtype=np.int32)
print(arr1.dtype)
print(arr2.dtype)

更多数组类型请参考该书的 表4-2

import numpy as np

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

arr1 = arr1.astype(np.int32)
print(arr1.dtype)
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings = numeric_strings.astype(np.float64)
print(numeric_strings)

empty_unit32 = np.empty(8, dtype='u4')
print(empty_unit32, empty_unit32.dtype)

使用 astype时 会生成一个新的数组,即使你传入的dtype 与之前一样。

3. NumPy 数组算术

数组之所以重要,是因为它允许进行批量操作而无须进行任何 for 循环。这一特性 也称为 向量化。

import numpy as np

arr = np.array([[1., 2., 3.], [4., 5., 6.]])
print(arr * arr)
print(arr - arr)

print(1 / arr)
print(arr ** 0.5)

arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
print(arr2 > arr)

4. 基础索引与切片

NumPy 数组索引 方式有很多种

import numpy as np

arr = np.arange(10)
print(arr)

print(arr[5])

print(arr[5:8])

arr[5:8] = 12

print(arr)

arr_slice = arr[5:8]

arr_slice[1] = 12345
print(arr)

arr_slice[:] = 13
print(arr)

copy = arr[5:8].copy()
copy[:] = 0
print(copy)
print(arr)

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[0])

print(arr2d[0][2], arr2d[0, 2])

arr2d[0][2] = 5
print(arr2d)

4.1 切片索引

其实这种索引方式在上面有所提及,对于高维数组,我们可以使用切片索引获取低维度的切片,并重新赋值

import numpy as np

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[:2, 2])
arr2d[:2, :1] = 0
print(arr2d)

5. 布尔索引

其实就是bool值去索引, 需注意的是,布尔值数组长度应该和数组轴索引长度一致, 且可能是因为用C编写的原因,and和or关键字对布尔值数组没有用,需要使用 & 和 | 替代。

import numpy as np

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
print(names == 'Bob')
print(data[names == 'Bob'])
print(data[~(names == 'Bob')])
mask = (names == 'Bob') | (names == 'Will')
print(data[mask])
data[data < 0] = 0
print(data)

6. 神奇索引

其实就是用整数数组进行索引

import numpy as np

arr = np.empty((8, 4))
print(arr[[4, 3, 0, -6]])

arr = np.arange(32).reshape((8, 4))
print(arr)

print(arr[[1, 5, 7, 2], [0, 3, 1, 2]])

print(arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]])

7. 数组转置和换轴

import numpy as np

arr = np.arange(15).reshape((3, 5))
print(arr)
print(arr.T)

print(np.dot(arr, arr.T))
arr1 = np.arange(16).reshape((2, 2, 4))

print(arr1.transpose((1, 0, 2)))
print(arr1)

print(arr1.swapaxes(1, 2))

以上方法,都是返回数据的底层视图,而不生成新的数组,也不对数据进行复制

二 通用函数

通用函数,ufunc,是一种在 ndarray 数据中 进行逐元素操作的函数,某些简单函数接收一个或多个标量差值, 并产生 一个或多个 标量结果, 而通用函数就是对这些函数是对这些简单函数的向量化封装

import numpy as np

arr = np.arange(10)
print(np.sqrt(arr))
print(np.exp(arr))

x = np.random.randn(8)
y = np.random.randn(8)
print(x, y)

print(np.maximum(x, y))

reminder, whole_part = np.modf(x)
print(reminder)
print(whole_part)
arr = np.random.randn(7) * 5
print(arr)

更多的通用函数请参考该书的表 4-3,4-4

三 使用数组进行面向数组编程

使用Numpy数组,可以使用简单的数组表达式代替显示循环的方法, 这种方法称为向量化,向量化的数组操作会比纯Python的等价实现在速度上更快

import numpy as np

points = np.arange(-5, 5, 0.01)

xs, ys = np.meshgrid(points, points)
print(ys)
z = np.sqrt(xs ** 2 + ys ** 2)
print(z)

import matplotlib.pyplot as plt
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.show()

1. 将条件逻辑作为数组操作

这里主要讲的是where函数, 其实就是三元表达式 x if condition else y 的向量化版本。如果直接使用三元表达式,其需要解释器解释python完成, 速度会很慢,且对高维数组需要修改代码,无法轻易复用。而使用哪np.where就可以非常简单的完成

import numpy as np

xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = [(x if c else y)
          for x, y, c in zip(xarr, yarr, cond)]
print(result)

result = np.where(cond, xarr, yarr)
print(result)

arr = np.random.randn(4, 4)
print(arr)
print(arr > 0)

print(np.where(arr > 0, 2, -2))

print(np.where(arr > 0, 2, arr))

传递给 np.where 的数组既可以是同等大小的数组,也可以是标量

2. 数学和统计方法

import numpy as np

arr = np.random.randn(5, 4)
print(arr)
print(arr.mean())

print(np.mean(arr))

print(arr.mean(1))

print(arr.sum(axis=0))

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
print(arr.cumsum())

arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
print(arr.cumsum(axis=0))
print(arr.cumprod(axis=1))

更多地请参考该书的表4-5,然后提一句,该书在该页有一个问题,axis=0 是表示每一行,axis=1 表示每一列

3. 布尔值数组的方法

布尔值会被强制为 1(True)和 0(False)

import numpy as np

arr = np.random.randn(100)
print((arr > 0).sum())

bools = np.array([False, False, True, True])

print(bools.any())

print(bools.all())

这些方法也适用非布尔值数组,所有非0的元素都按 True 处理

4. 排序

import numpy as np

arr = np.random.randn(6)
print(arr)
arr.sort()
print(arr)

arr = np.random.randn(5, 3)
print(arr)
arr.sort(1)
print(arr)

顶层的 np.sort 方法 返回的是已经排序好的数组拷贝,而不是对原数组继续拷贝

5. 唯一值与其他集合逻辑

NumPy 包含一些针对一维nadarray 的基础集合操作,一个常用的方法是 np.unique,返回的是数组中唯一值排序后形成的数组

import numpy as np

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
print(np.unique(names))
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
print(np.unique(ints))

另一个函数, np.in1d, 可以检查一个数组中的值是否存在另外一个数组中,并返回一个布尔值数组

import numpy as np

values = np.array([6, 0, 0, 3, 2, 5, 6])
print(np.in1d(values, [2, 3, 6]))

更多的ndarray数组的集合操作,请参考表 4-6

四 使用数组进行文件输入和输出

import numpy as np

arr = np.arange(10)
np.save('som_array', arr)
print(np.load('som_array.npy'))

np.savez('array_archive.npz', a=arr, b=arr)
arch = np.load('array_archive.npz')
print(arch['b'])

np.savez_compressed('array_compressed.npz', a=arr, b=arr)
print(np.load('array_compressed.npz'))

五 线性代数

这部分函数大多集合在了numpy的linalg中

import numpy as np
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
print(x.dot(y))

print(np.dot(x, y))

print(x @ y)

from  numpy.linalg import inv, qr
X = np.random.randn(5, 5)
mat = X.T.dot(X)
print(inv(mat))
print(mat.dot(inv(mat)))
q, r = qr(mat)
print(r)

更多的线性代数操作方法,请参考表4-7

六 伪随机数生成

import numpy as np

samples = np.random.normal(size=(4, 4))
print(samples)

np.random.seed(1234)

rng = np.random.RandomState(1234)
print(rng.randn(10))

其他numpy.random 中的部分函数列表参考表 4-8

七 示例:随机漫步

一个简单的随机漫步

import matplotlib.pyplot as plt
import numpy as np
import random

position = 0
walk = [position]
steps = 1000
for i in range(steps):
    step = 1 if random.randint(0, 1) else -1
    position += step
    walk.append(position)

nsteps = 1000
draws = np.random.randint(0, 2, size =nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()

print(walk.min(), walk.max())

print((np.abs(walk) >= 10).argmax())

plt.plot(walk[:100])
plt.show()

1. 一次性模拟多次随机漫步

import matplotlib.pyplot as plt
import numpy as np
import random

nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size=(nwalks, nsteps))
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum(1)
print(walks)

print(walks.max(), walks.min())

hits30 = (np.abs(walks) >= 30).any(1)
print(hits30)
print(hits30.sum())

crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)
print(crossing_times)
print(crossing_times.mean())

小结

本书接下来的部分将会集中在打造 pandas 数据处理技能上,继续在基于数组的风格下处理数据

终于写完了,最近的效率真的低下
_

Original: https://blog.csdn.net/weixin_54891898/article/details/122792809
Author: 物联黄同学
Title: NumPy 基础(数组与向量化计算)——《利用Python进行数据分析》第四章阅读笔记

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/763447/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【移动安全】—apk反编译基础及静态分析

    作者名:Demo不是emo 主页面链接:主页传送门创作初心: 一切为了她座右铭:不要让时代的悲哀成为你的悲哀专研方向:网络安全,数据结构每日emo: ctf被大佬吊打的一天,裂开 …

    Python 2023年11月6日
    044
  • 【HTML】纯CSS居然能做出这种效果,一款宝藏网页分享(超详细讲解 | 附源码)

    💂 作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。…

    Python 2023年11月6日
    053
  • Nginx下的反向代理 双层代理 负载均衡

    最近正在开发项目,即用到了Java的Spring Boot,又用到了Python的Flask,为了保证在同一域名下访问,我使用了Nginx做反向代理,只代理一个还比较好配置,代理的…

    Python 2023年8月14日
    053
  • pandas模块的基本使用

    numpy能够帮助我们处理数值,但是pandas除了能处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据pandas技术文档:https://pandas.pydat…

    Python 2023年8月9日
    071
  • 在pygame中实现菜单,支持鼠标和键盘操作

    python中的pygame库,并没有传统菜单功能,正好手边有一项目,需要在pygame中实现菜单功能。目前,项目已经完成,将其中实现菜单功能的约400行代码摘取出来,供大家参考。…

    Python 2023年9月17日
    036
  • Scrapy爬虫框架学习_intermediate

    一.Scrapy爬虫框架介绍 Scrapy是功能强大的非常快速的网络爬虫框架,是非常重要的python第三方库。scrapy不是一个函数功能库,而是一个爬虫框架。 1.1 Scra…

    Python 2023年10月1日
    049
  • 老油条用什么工具写文档?

    写代码,哪个程序员都不害怕。 写文档,哪个程序员都害怕! 为什么? 还不是因为 API 工具不好使,不便捷,同步麻烦,测试看不懂…… 最近调研了身边一些开发…

    Python 2023年8月9日
    075
  • Anaconda安装及pygame的安装

    python有很多版本,还是Anaconda最好用啦,因为它有强大而方便的包管理与环境管理的功能。。。 Pygame是Python最经典的2D游戏开发第三方库,也支持3D游戏开发,…

    Python 2023年9月25日
    055
  • pytest 重试_pytest 使用

    import pytest from web_ui_YXBI.test_datas.common_datas import Common_Datas as c from selen…

    Python 2023年9月12日
    054
  • Python — — turtle 常用代码

    目录 一、设置画布 二、画笔 1、画笔属性 2、绘图命令 (1) 画笔运动命令 (2) 画笔控制命令 (3) 全局控制命令 (4) 其他命令 3. 命令详解 三、文字显示为一个圆圈…

    Python 2023年7月31日
    053
  • 量化研究之“大A打板敢死队”是如何做换手板与撬板的?

    更多精彩内容, 欢迎关注公众号:数量技术宅,也可添加技术宅 个人微信号:sljsz01,与我交流。 涨停跌停板分类 涨停、跌停是A股特有的现象,其他主要市场,例如美股、港股都不存在…

    Python 2023年6月3日
    0108
  • JUC包(java.util.concurrent)下的常用子类

    文章目录 前言 一、对象锁juc.locks包 二、原子类 三、四个常用工具类 * 3.1 信号量 Semaphore 3.2 CountDownLatch 总结 前言 博主个人社…

    Python 2023年9月17日
    046
  • 都什么年代了,你居然还连不上GitHub?

    前言 众所周知,GitHub是我们程序员在上班或者学习的时候经常会逛的一个地方[手动狗头],而且如果我们想参与开源项目的话,GitHub也是一个很好的平台。 可问题是,GitHub…

    Python 2023年9月16日
    038
  • 网站建设 之 用js写wasm

    为什么要这么做?编译js比解释js更快是必然的 wasm是什么? 我期望是一个二进制文件 WebAssembly(又名wasm)是一种高效的,低级别的编程语言。 它让我们能够使用J…

    Python 2023年11月6日
    058
  • 从零开始的天天生鲜项目

    ——Django天天生鲜项目 环境:Python 3.8.10Ubuntu 9.3.0-17ubuntu1~20.04Tinymce 2.7.0MySQL …

    Python 2023年8月5日
    038
  • 『Python-Django 智慧中医健康数字服务平台』开源项目总览

    文章目录 项目开发初衷 项目技术应用 中医科研成就 项目更新历程 专栏文章索引 UGC自媒体 数据化管理运营 问题汇总 ; 项目开发初衷 本人2018年-2020年曾就职于清华大学…

    Python 2023年8月4日
    072
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球