DW-Numpy_数据类型和数组重建

常量

  • numpy.nan:表示空值。两个numpy.nan是不相等的
  • numpy.isnan(x, *args, **kwargs) 返回布尔数组True/False Test element-wise for NaN and return result as a boolean array.
  • numpy.inf:表示正无穷大。
  • numpy.pi: 表示圆周率
  • numpy.e:表示自然常数

数据类型

常见数据类型

为了加以区分 numpy 在这些类型名称末尾都加了“_”。下表列举了常用 numpy 基本类型。

类型备注说明
bool_ = bool88位布尔类型
int8 = byte8位整型
int16 = short16位整型
int32 = intc32位整型
int_ = int64 = long = int0 = intp64位整型
uint8 = ubyte8位无符号整型
uint16 = ushort16位无符号整型
uint32 = uintc32位无符号整型
uint64 = uintp = uint0 = uint64位无符号整型
float16 = half16位浮点型
float32 = single32位浮点型
float_ = float64 = double64位浮点型
str_ = unicode_ = str0 = unicodeUnicode 字符串
datetime64日期时间类型
timedelta64表示两个时间之间的间隔

创建数据类型

numpy 的数值类型实际上是 dtype 对象的实例。

每个内建类型都有一个唯一定义它的字符代码,如下:

字符对应类型备注
bboolean‘b1’
isigned integer‘i1’(type:int8 itemsize:1), ‘i2’(int16 2), ‘i4’(32 4), ‘i8’
uunsigned integer‘u1’, ‘u2’ ,‘u4’ ,‘u8’(同上)
ffloating-point‘f2’(16 2), ‘f4’, ‘f8’
ccomplex floating-point
mtimedelta64表示两个时间之间的间隔
Mdatetime64日期时间类型
Oobject
S(byte-)stringS3(bytes_)表示长度为3的字符串
UUnicodeUnicode (U3:dtype:str_,itemsize:12)字符串
Vvoid

数据类型信息

Python 的浮点数通常是64位浮点数,几乎等同于 np.float64

NumPy和Python整数类型的行为在整数溢出方面存在显着差异,与 NumPy 不同,Python 的int 是灵活的。这意味着Python整数可以扩展以容纳任何整数并且不会溢出。

Machine limits for integer types.

ii16 = np.iinfo(np.int16)
print(ii16.min)  # -32768
print(ii16.max)  # 32767

Machine limits for floating point types.

ff16 = np.finfo(np.float16)
print(ff16.bits)  # 16
print(ff16.min)  # -65500.0
print(ff16.max)  # 65500.0
print(ff16.eps)  # 0.000977 #表示浮点相对精度 取非负的最小值


#具体作用和应用
eps = np.finfo(height.dtype).eps
height = np.maximum(height, eps)

dy = (base_ctr_y - ctr_y) / height
dh = xp.log(base_height / height)
dw = xp.log(base_width / width

这里可以看到有除法,我们要考虑到除法的分母是不能为0的,而且式子中log内也不能为负数,不然会直接跳出显示错误。

代码中是用上半部分来处理的,eps开始的三行将可能出现的负数和零,使用eps来替换,这样就不会出现错误了。

finfo函数是根据height.dtype类型来获得信息,获得符合这个类型的float型,eps是取非负的最小值。

时间日期和时间增量

datetime64 基础

在 numpy 中,我们很方便的将字符串转换成时间日期类型 datetime64datetime 已被 python 包含的日期时间库所占用)。
1秒 = 1000 毫秒

  • 从字符串创建 datetime64 类型时,默认情况下,numpy 会根据字符串自动选择对应的单位,也可以强制指定使用的单位。
a = np.datetime64('2020-03', 'D')
  • 从字符串创建 datetime64 数组时,如果单位不统一,则一律转化成其中最小的单位。
a = np.array(['2020-03', '2020-03-08', '2020-03-08 20:00'], dtype='datetime64')
print(a, a.dtype)
# ['2020-03-01T00:00' '2020-03-08T00:00' '2020-03-08T20:00'] datetime64[m]
  • 使用arange()创建 datetime64 数组,用于生成日期范围。np.arange(‘2020-08-01’, ‘2020-08-10’, dtype=np.datetime64)

datetime64 和 timedelta64 运算

  • timedelta64 表示两个 datetime64 之间的差。timedelta64 和相减运算中的两个 datetime64 中的较小的单位保持一致。
a = np.datetime64('2020-03') + np.timedelta64(20, 'D')
print(a, a.dtype)  # 2020-03-21 datetime64[D]
  • 生成 timedelta64时,要注意年(‘Y’)和月(‘M’)这两个单位无法和其它单位进行运算(一年有几天?一个月有几个小时?不确定)。

  • timedelta64 的运算

c = np.timedelta64(1, 'W')
d = np.timedelta64(1, 'D')
print(c / d)  # 7.0
  • numpy.datetime64(2020-06-01T20:05:30) 与 datetime.datetime(2020-06-01 20:05:30) 相互转换A.astype(B)
import numpy as np
import datetime

dt = datetime.datetime(year=2020, month=6, day=1, hour=20, minute=5, second=30)
dt64 = np.datetime64(dt, 's')
print(dt64, dt64.dtype)
# 2020-06-01T20:05:30 datetime64[s]

dt2 = dt64.astype(datetime.datetime)
print(dt2, type(dt2))
# 2020-06-01 20:05:30 <class 'datetime.datetime'>

datetime64 的应用

为了允许在只有一周中某些日子有效的上下文中使用日期时间,NumPy包含一组“busday”(工作日)功能。
numpy.busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)

  • 将指定的偏移量应用于工作日,单位天(‘D’)。计算下一个工作日,如果当前日期为非工作日,默认报错。可以指定 forwardbackward 规则来避免报错。(一个是向前取未来第一个有效的工作日,一个是向后取过去第一个有效的工作日)
    可以指定偏移量为 0 来获取当前日期向前或向后最近的工作日,当然,如果当前日期本身就是工作日,则直接返回当前日期。
# 2020-07-10 星期五
a = np.busday_offset('2020-07-10', offsets=1)
print(a)  # 2020-07-13

a = np.busday_offset('2020-07-11', offsets=1)
print(a)  # ValueError: Non-business day date in busday_offset

a = np.busday_offset('2020-07-11', offsets=0, roll='forward')
print(a)  # 2020-07-13

a = np.busday_offset('2020-07-11', offsets=1, roll='forward')
print(a)  # 2020-07-14
  • 返回指定日期是否是工作日:np.is_busday(‘2020-07-10’) # True

  • 统计一个 datetime64[D] 数组中的工作日天数:np.count_nonzero(np.is_busday(a)) / 两个日期之间的工作日数量numpy.busday_count()
    numpy.busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)Counts the number of valid days between begindates and enddates, not including the day of enddates.

  • 自定义周掩码值,即指定一周中哪些星期是工作日:np.is_busday(‘2020-07-10’, weekmask=[1, 1, 1, 1, 1, 0, 0]) #True

数组的创建

numpy 提供的最重要的数据结构是ndarray,它是 python 中list的扩展。

1. 依据现有数据来创建 ndarray

  • (a)通过array()函数进行创建。
    np.array([0, 1, 2, 3, 4])

  • (b)通过asarray()函数进行创建

array()asarray()都可以将结构数据(list)转化为 ndarray(np.array([1,2])=np.asarray([1,2]))

但是array()asarray()主要区别就是当数据源是ndarray 时,array()仍然会 copy 出一个副本,占用新的内存(和改变前ndarray相同),但不改变 dtype 时 asarray()不会。

import numpy as np

x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
y = np.array(x)
z = np.asarray(x)
x[1][2] = 2
print(x,type(x),x.dtype)
# [[1 1 1]
#  [1 1 2]
#  [1 1 1]] <class 'numpy.ndarray'> int32

print(y,type(y),y.dtype)
# [[1 1 1]
#  [1 1 1]
#  [1 1 1]] <class 'numpy.ndarray'> int32

print(z,type(z),z.dtype)
# [[1 1 1]
#  [1 1 2]
#  [1 1 1]] <class 'numpy.ndarray'> int32

更改为较大的dtype时,其大小必须是array的最后一个axis的总大小(以字节为单位)的除数 ?!

import numpy as np

x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
print(x, x.dtype)
# [[1 1 1]
#  [1 1 1]
#  [1 1 1]] int32
x.dtype = np.float

# ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.
  • (c)通过fromfunction()函数进行创建

给函数绘图的时候可能会用到fromfunction(),该函数可从函数中创建数组。

def fromfunction(function, shape, **kwargs):
import numpy as np

def f(x, y):
    return 10 * x + y

x = np.fromfunction(f, (5, 4), dtype=int)
print(x)
# [[ 0  1  2  3]
#  [10 11 12 13]
#  [20 21 22 23]
#  [30 31 32 33]
#  [40 41 42 43]]

x = np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
print(x)
# [[ True False False]
#  [False  True False]
#  [False False  True]]

x = np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
print(x)
# [[0 1 2]
#  [1 2 3]
#  [2 3 4]]

2.随机初始化矩阵

zeros(shape) zeros_like(x)

  • zeros()函数:返回给定形状和类型的零数组。

  • zeros_like()函数:返回与给定数组形状和类型相同的零数组。

  • ones()函数:返回给定形状和类型的1数组。

  • ones_like()函数:返回与给定数组形状和类型相同的1数组。

  • empty()函数:返回一个空数组,数组元素为随机数。

  • empty_like函数:返回与给定数组具有相同形状和类型的新数组。

  • eye()函数:返回一个对角线上为1,其它地方为零的单位数组。eye(4):4*4

  • identity()函数:返回一个方的单位数组。

  • diag(v, k=0)函数:提取对角线或构造对角数组。k表示对角线上方的第几条线(负数表示下方) np.diag(v)构造以v为对角线的数组

  • full(shape,const)函数:返回一个常数数组。

  • full_like()函数:返回与给定数组具有相同形状和类型的常数数组。

3. 利用数值范围来创建ndarray

  • arange()函数:返回给定间隔内的均匀间隔的值。
  • linspace()函数:返回指定间隔内的等间隔数字。
  • logspace()函数:返回数以对数刻度均匀分布。 相当于 10 ** i for i in x (x是linspace产生的)
  • numpy.random.rand() 返回一个由[0,1)内的随机数组成的数组。
x = np.logspace(0, 1, 5)
print(np.around(x, 2))
# [ 1.    1.78  3.16  5.62 10.  ]            
                                    #np.around 返回四舍五入后的值,可指定精度。
                                   # around(a, decimals=0, out=None)
                                   # a 输入数组
                                   # decimals 要舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置

x = np.linspace(start=0, stop=1, num=5)
x = [10 ** i for i in x]
print(np.around(x, 2))
# [ 1.    1.78  3.16  5.62 10.  ]

4. 结构数组的创建

结构数组,首先需要定义结构,然后利用np.array()来创建数组,其参数dtype为定义的结构。

  • (a)利用字典来定义结构
personType = np.dtype({
    'names': ['name', 'age', 'weight'],
    'formats': ['U30', 'i8', 'f8']})

a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],
             dtype=personType)
print(a, type(a))
# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]
# <class 'numpy.ndarray'>
  • (b)利用包含多个元组的列表来定义结构
import numpy as np

personType = np.dtype([('name', 'U30'), ('age', 'i8'), ('weight', 'f8')])
a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],
             dtype=personType)
print(a, type(a))
# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]
# <class 'numpy.ndarray'>

# 结构数组的取值方式和一般数组差不多,可以通过下标取得元素:
print(a[0])
# ('Liming', 24, 63.9)

print(a[-2:])
# [('Mike', 15, 67. ) ('Jan', 34, 45.8)]

# 我们可以使用字段名作为下标获取对应的值
print(a['name'])
# ['Liming' 'Mike' 'Jan']
print(a['age'])
# [24 15 34]
print(a['weight'])
# [63.9 67.  45.8]

数组的属性

在使用 numpy 时,你会想知道数组的某些信息。很幸运,在这个包里边包含了很多便捷的方法,可以给你想要的信息。

  • numpy.ndarray.ndim用于返回数组的维数(轴的个数)也称为秩,一维数组的秩为 1,二维数组的秩为 2,以此类推。
  • numpy.ndarray.shape表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。
  • numpy.ndarray.size数组中所有元素的总量,相当于数组的shape中所有元素的乘积,例如矩阵的元素总量为行与列的乘积。
  • numpy.ndarray.dtype ndarray 对象的元素类型。
  • numpy.ndarray.itemsize以字节的形式返回数组中每一个元素的大小。

ndarray中所有元素必须是同一类型,否则会自动向下转换,int->float->str
b = np.array([1, 2, 3, 4, ‘5’])
print(b) # [‘1’ ‘2’ ‘3’ ‘4’ ‘5’]

部分练习

1.numpy是python中基于数组对象的科学计算库。
提炼关键字,可以得出numpy以下三大特点:
拥有n维数组对象;
拥有广播功能(后面讲到);
拥有各种科学计算API,任你调用;

print(0 * np.nan)# nan
print(np.nan == np.nan)# False
print(np.inf > np.nan)# False
print(np.nan - np.nan)# nan
print(0.3 == 3 * 0.1)# False

3.填充缺失的日期,使其成为连续的日期序列

import numpy as np

dates = np.arange('2020-02-01', '2020-02-10', 2, np.datetime64)
print(dates)
# ['2020-02-01' '2020-02-03' '2020-02-05' '2020-02-07' '2020-02-09']

out = []
for date, d in zip(dates, np.diff(dates)):
    out.extend(np.arange(date, date + d))
fillin = np.array(out)
output = np.hstack([fillin, dates[-1]])
print(output)
# ['2020-02-01' '2020-02-02' '2020-02-03' '2020-02-04' '2020-02-05'
#  '2020-02-06' '2020-02-07' '2020-02-08' '2020-02-09']
4.#得到当下时间日期
yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D')
today     = np.datetime64('today', 'D')
tomorrow  = np.datetime64('today', 'D') + np.timedelta64(1, 'D')
5.#创建布尔数组
import numpy as np

arr = np.full([3, 3], True, dtype=np.bool)
print(arr)
# [[ True  True  True]
#  [ True  True  True]
#  [ True  True  True]]

6.创建一个二维数组,其中边界值为1,其余值为0

Z = np.ones((10,10))
Z[1:-1,1:-1] = 0
print(Z)

7.将本地图像导入并将其转换为numpy数组

import numpy as np
from PIL import Image

img1 = Image.open('Scarlett.jpg')
a = np.array(img1)

print(a.shape, a.dtype)
# (700, 500, 3) uint8
(700, 500, 3) uint8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值