本文是根据
DataWhale『巨硬的numpy』文档进行学习, 辅之以天池平台, 之前学习过, 此时进行进一步的整理, 着重学习未完全熟悉的知识点.详细的代码我也放入了天池学习的AI训练营合集中
常量
空值
使用 np.nan 来表示空值, 需要注意的是: 空值之间并不相等!
1 | print(np.nan == np.nan) # False |
可以使用 np.isnan 来检查空值
1 | x = np.array([1, 1, 8, np.nan, 10]) |
如果需要计算空值的个数, 则可以使用计算非零数 count_nonzero 来等价使用, 因为布尔值就分别代表了 0 和 1.
1 | z = np.count_nonzero(y) |
无穷大
以下这几个都可以
1 | np.inf |
圆周率 \(\pi\)
1 | np.pi |
自然常数 \(e\)
1 | np.e |
数据类型
在原生的 python 中, 数据类型较少, 但进行科学计算的时候, 需要对数据有更多的控制, 所以数据类型相对而言很丰富了.
在后续的创建数组时, 可以使用参数 dtype 来规定数据的类型. 与 python 原生类型相同的, 则会在类型后加入一个下划线以示区分, 例如 bool_, 常见的数据类型如下:
| 类型 | 备注 | 说明 |
|---|---|---|
| bool_ = bool8 | 8位 | 布尔类型 |
| int8 = byte | 8位 | 整型 |
| int16 = short | 16位 | 整型 |
| int32 = intc | 32位 | 整型 |
| int_ = int64 = long = int0 = intp | 64位 | 整型 |
| uint8 = ubyte | 8位 | 无符号整型 |
| uint16 = ushort | 16位 | 无符号整型 |
| uint32 = uintc | 32位 | 无符号整型 |
| uint64 = uintp = uint0 = uint | 64位 | 无符号整型 |
| float16 = half | 16位 | 浮点型 |
| float32 = single | 32位 | 浮点型 |
| float_ = float64 = double | 64位 | 浮点型 |
| str_ = unicode_ = str0 = unicode | Unicode 字符串 | |
| datetime64 | 日期时间类型 | |
| timedelta64 | 表示两个时间之间的间隔 |
而我们内建的数据类型会有一个与其唯一对应的字符代码, 如下:
| 字符 | 对应类型 | 备注 |
|---|---|---|
| b | boolean | 'b1' |
| i | signed integer | 'i1', 'i2', 'i4', 'i8' |
| u | unsigned integer | 'u1', 'u2' ,'u4' ,'u8' |
| f | floating-point | 'f2', 'f4', 'f8' |
| c | complex floating-point | |
| m | timedelta64 | 表示两个时间之间的间隔 |
| M | datetime64 | 日期时间类型 |
| O | object | |
| S | (byte-)string | S3表示长度为3的字符串 |
| U | Unicode | Unicode 字符串 |
| V | void |
查看数据类型
type 是查看对象的类型, 而想要查看矩阵内的元素类型, 则可以使用 dtype.
1 | a = np.array([1,2,3], dtype=np.float32) |
日期和时间
日期时间类型 datetime64
很多情况下, 我们需要字符串日期转化为时间类型, 在 numpy 中可以很方便的将字符串转换成时间日期类型 datetime64.
| 日期单位 | 代码含义 | 时间单位 | 代码含义 |
|---|---|---|---|
| Y | 年 | h | 小时 |
| M | 月 | m | 分钟 |
| W | 周 | s | 秒 |
| D | 天 | ms | 毫秒 |
| - | - | us | 微秒 |
| - | - | ns | 纳秒 |
| - | - | ps | 皮秒 |
| - | - | fs | 飞秒 |
| - | - | as | 阿托秒 |
从字符串创建 datetime64 类型时, 会自动选择对应的单位.
1 | a = np.datetime64('2022-02') |
但也能够强制指定类型
1 | a = np.datetime64('2022-02', 'Y') |
在时间数组中, 若单位不统一, 则全部转化为最小的单位.
1 | a = np.array(['2022-02', '2022-02-19', '2020-02-19 17:16'], dtype='datetime64') |
使用 arange 也可以生成时间类型的数组, 若时间单位不一致, 则按照较小的单位作为间隔生成时间区间.
1 | a = np.arange('2022-02', '2022-05', dtype=np.datetime64) |
日期时间差 timedelta64
timedelta64 表示两个 datetime64 之间的差, 其单位与相减运算中的两个 datetime64 中的较小的单位保持一致.
1 | a = np.datetime64('2022-02-19') - np.datetime64('2022-02-02') |
除了计算时间差得到 timedelta64 类型, 该类型还可以直接创建, 表示有多少个时间单位, 并可以进行四则运算.
1 | a = np.timedelta64(2, 'Y') |
需要注意的是: 'Y'和'M'类型是无法与其他类型进行计算的, 因为无法确定一年有多少天, 一个月有多少天的问题.
那么这样可以进行加法计算, 实现在多久之前和多久之后的计算.
计算结果的单位依旧以较小的为准
1 | a = np.datetime64('2022-02') + np.timedelta64(20, 'D') |
数组的时间格式 datetime64 和 datetime 库中的时间格式 datetime 相互转换
1 | import datetime |
工作日
有些应用场景只有工作日的数据需要操作, 那么在这里也包含了 busday 功能, 可以计算 offset 天后的工作日.
1 | # 2022-02-18 是星期五 |
若操作的时间本身不是工作日, 则会报错, 例如 '2022-02-19' 是周六, 那么将会抛出 ValueError.
这时可以使用参数 roll 来找到前一个 (forward) 或后一个 (backward) 工作日.
前一个指: 例如 21 号在 19 号之前; 后一个指: 例如 18 号在 19 号之后; 这个概念和平时理解的前天后天顺序不一样, 是类似数字大小的概念 😂.
1 | # 2022-02-19 是星期六 |
判断是否是工作日也很简单, 使用 np.is_busday 即可.
1 | a = np.is_busday('2022-02-18') |
例如统计数组中的工作日天数, 可以结合布尔值和计算非零数的方法 count_nonzero 进行解决.
1 | a = np.arange('2022-02-01', '2022-03', dtype=np.datetime64) |
对于日期区间内的工作日天数, 则可以直接使用 busday_count 来计算.
1 | cnt = np.busday_count('2022-02', '2022-03') |
最后, 工作日还可以进行自定义, 毕竟一周可不是只上班五天呢~ (不是). 使用 0/1 表示周几属于工作日.
1 | # 2022-02-18 是星期五 |
个人收获
本章对数据类型进行了一个汇总, 尤其是数据类型对于的字符代码, 之前不是很清楚什么 U 啊之类的, 这次整理好了, 可以方便以后查询.
还有日期类型, 之前还好奇为何多了一个 64 在 datetime 后面, 原来是为了进行区分. 并熟悉了工作日的使用方法.
还有一个就是学到了计算非零数的函数 count_nonzero 可以与布尔数组联合使用, 达到计算满足条件的元素个数的目的.