本文是根据
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
可以与布尔数组联合使用, 达到计算满足条件的元素个数的目的.