task01数据类型及数组创建

数据类型及数组创建

01 常量

numpy.nan

  • nan = NaN = NAN,注意:两个numpy.nan是不相等的!

  • numpy.isnan(x,*args,**kwargs)用来检测空值,返回bool值向量

numpy.inf

  • 表示正无穷大,Inf = inf =infty = Infinity = PINF

    print(0 * np.nan)
    print(np.nan == np.nan)
    print(np.inf > np.nan)
    print(np.nan - np.nan)
    print(0.3 == 3 * 0.1)
    # nan
    # False
    # False
    # nan
    # False  
    # ⭐由于浮点数在机器里都是二进制运算,十进制的小数转化成二进制可能是无穷的,但机器只能取有穷计算完以后恢复成十进制就会有偏差
    # 所以对于计算得到的浮点数不要用 == 来进行判断,无法得到十进制意义上的绝对相等
    

numpy.pi

numpy.e

  • 自然常数

02 数据类型

常见数据类型

bool、int、float、str是python原生的数据类型,为了加以区分,在numpy中这些数据类型名称末尾加了“_”。同时由于科学计算通常需要更多的控制,所以numpy将数据类型进行了扩展。

下表列举了常用numpy基本类型:

类型 备注 说明
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 表示两个时间之间的间隔

创建数据类型

numpy的数据类型实际上是dtype对象的实例(python里面的原生数据类型也是)

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

字符 对应类型 备注
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

数据类型溢出

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

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

numpy.int16最小值为-32768,最大值为32767

numpy.int32最小值为-2147483648,最大值为2147483647

numpy.float16最小值为-65500.0,最大值为65500.0,精度为0.000977

numpy.float32最小值为-3.4028235e+38,最大值为3.4028235e+38,精度为1.1920929e-07

03 时间日期和时间增量

datetime64

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

datatime64是带单位的日期时间类型,其单位如下:

日期单位 代码含义 时间单位 代码含义
Y h 小时
M m 分钟
W s
D ms 毫秒
- - us 微秒
- - ns 纳秒
- - ps 皮秒
- - fs 飞秒
- - as 阿托秒
  • 从字符串创建 datetime64 类型时,默认情况下,numpy 会根据字符串自动选择对应的单位。
import numpy as np

a = np.datetime64('2020-03-01')
print(a, a.dtype)  # 2020-03-01 datetime64[D]

a = np.datetime64('2020-03')
print(a, a.dtype)  # 2020-03 datetime64[M]

a = np.datetime64('2020-03-08 20:00:05')
print(a, a.dtype)  # 2020-03-08T20:00:05 datetime64[s]

a = np.datetime64('2020-03-08 20:00')
print(a, a.dtype)  # 2020-03-08T20:00 datetime64[m]

a = np.datetime64('2020-03-08 20')
print(a, a.dtype)  # 2020-03-08T20 datetime64[h]
  • 从字符串创建 datetime64 类型时,可以强制指定使用的单位。
import numpy as np

a = np.datetime64('2020-03', 'D')
print(a, a.dtype)  # 2020-03-01 datetime64[D]

a = np.datetime64('2020-03', 'Y')
print(a, a.dtype)  # 2020 datetime64[Y]

print(np.datetime64('2020-03') == np.datetime64('2020-03-01'))  # True
print(np.datetime64('2020-03') == np.datetime64('2020-03-02'))  #False
  • 从字符串创建 datetime64 数组时,如果单位不统一,则一律转化成其中最小的单位。
  • 使用np.arange()创建 datetime64 数组,用于生成日期范围。

datetime64和timedelta64运算

  • timedelta64 表示两个 datetime64 之间的差。timedelta64 也是带单位的,并且和相减运算中的两个 datetime64 中的较小的单位保持一致。
  • 生成 timedelta64时,要注意年(‘Y’)和月(‘M’)这两个单位无法和其它单位进行运算(一年有几天?一个月有几个小时?这些都是不确定的)。
  • timedelta64 的运算。
import numpy as np

a = np.timedelta64(1, 'Y')
b = np.timedelta64(6, 'M')
c = np.timedelta64(1, 'W')
d = np.timedelta64(1, 'D')
e = np.timedelta64(10, 'D')

print(a)  # 1 years
print(b)  # 6 months
print(a + b)  # 18 months
print(a - b)  # 6 months
print(2 * a)  # 2 years
print(a / b)  # 2.0
print(c / d)  # 7.0
print(c % e)  # 7 days
  • numpy.datetime64 与 datetime.datetime 相互转换,

    np.dt64 → \rightarrow dt:dt64.astype(datetime.datetime)

    dt → \rightarrow np.dt64:np.datetime(dt,"label")

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_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)

参数roll{'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}如果输入的日期不属于工作日,则按照roll定义的规则来执行。

    • ‘raise’ means to raise an exception for an invalid day.返回错误
    • ‘nat’ means to return a NaT (not-a-time) for an invalid day.
    • ‘forward’ and ‘following’ mean to take the first valid day later in time.向前取第一个有效的工作日
    • ‘backward’ and ‘preceding’ mean to take the first valid day earlier in time.向后取第一个有效的工作日
>>>np.busday_offset(["2020-10-19",'2020-10-18'],offsets = 1,roll = "backward")
[out]array(['2020-10-20', '2020-10-19'], dtype='datetime64[D]')
  • numpy.is_busday(dates, weekmask="1111100", holidays=None, busdaycal=None,out=None)

    # 自定义周掩码值,即指定一周中哪些星期是工作日
    import numpy as np
    
    # 2020-10-18 星期日
    a = np.is_busday('2020-10-18', weekmask=[1, 1, 1, 1, 0, 0, 1])
    b = np.is_busday('2020-10-18', weekmask=[1, 1, 1, 1, 1, 0, 0])
    print(a)  # True
    print(b)  # False
    
    # 统计一个 datetime64[D] 数组中的工作日天数
    import numpy as np
    
    # 2020-07-10 星期五
    begindates = np.datetime64('2020-07-10')
    enddates = np.datetime64('2020-07-20')
    a = np.arange(begindates, enddates, dtype='datetime64')
    b = np.count_nonzero(np.is_busday(a))
    print(a)
    # ['2020-07-10' '2020-07-11' '2020-07-12' '2020-07-13' '2020-07-14'
    #  '2020-07-15' '2020-07-16' '2020-07-17' '2020-07-18' '2020-07-19']
    print(b)  # 6
    
  • numpy.busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)

    # 返回两个日期之间的工作日数量
    import numpy as np
    
    # 2020-07-10 星期五
    begindates = np.datetime64('2020-07-10')
    enddates = np.datetime64('2020-07-20')
    a = np.busday_count(begindates, enddates)
    b = np.busday_count(enddates, begindates)
    print(a)  # 6
    print(b)  # -6
    

04 数组的创建

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

(a) 通过array()函数创建

可以将list和tuple转换成ndarray

def array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
(b)通过asarray()函数创建
def asarray(a, dtype=None, order=None):
    return array(a, dtype, copy=False, order=order)

array()asarray()的区别。(array()asarray()主要区别就是当数据源是ndarray 时,array()仍然会 copy 出一个副本,占用新的内存,但不改变 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)
w = np.asarray(x, dtype=np.int)
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

print(w,type(w),w.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()函数创建
def fromfunction(function, shape, **kwargs):

通过对生成的ndarray每个元素的坐标值(x,y)执行函数来构造数组,给函数绘图的时候比较有用。

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. 依据ones和zeroes填充

常常用于初始化

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

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

    def zeros(shape, dtype=None, order='C'):
    def zeros_like(a, dtype=None, order='K', subok=True, shape=None):
    
import numpy as np

x = np.zeros(5)
print(x)  # [0. 0. 0. 0. 0.]
x = np.zeros([2, 3])
print(x)
# [[0. 0. 0.]
#  [0. 0. 0.]]

x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.zeros_like(x)
print(y)
# [[0 0 0]
#  [0 0 0]]
(b)1数组
  • ones()函数:返回给定形状和类型的1数组。

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

    def ones(shape, dtype=None, order='C'):
    def ones_like(a, dtype=None, order='K', subok=True, shape=None):
    
(c)空数组
  • empty()函数:返回一个空数组,数组元素为随机数

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

    def empty(shape, dtype=None, order='C'): 
    def empty_like(prototype, dtype=None, order='K', subok=True, shape=None):
    
import numpy as np

x = np.empty(5)
print(x)
# [1.95821574e-306 1.60219035e-306 1.37961506e-306 
#  9.34609790e-307 1.24610383e-306]

x = np.empty((3, 2))
print(x)
# [[1.60220393e-306 9.34587382e-307]
#  [8.45599367e-307 7.56598449e-307]
#  [1.33509389e-306 3.59412896e-317]]

x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.empty_like(x)
print(y)
# [[  7209029   6422625   6619244]
#  [      100 707539280       504]]
(d)单位数组
  • eye()函数:返回一个对角线上为1,其它地方为零的单位数组。

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

    def eye(N, M=None, k=0, dtype=float, order='C'):
    def identity(n, dtype=None):
    
x = np.eye(4)
print(x)
# [[1. 0. 0. 0.]
#  [0. 1. 0. 0.]
#  [0. 0. 1. 0.]
#  [0. 0. 0. 1.]]

x = np.eye(2, 3)
print(x)
# [[1. 0. 0.]
#  [0. 1. 0.]]

x = np.identity(4)
print(x)
# [[1. 0. 0. 0.]
#  [0. 1. 0. 0.]
#  [0. 0. 1. 0.]
#  [0. 0. 0. 1.]]
(e)对角数组
  • diag()函数:提取对角线或构造对角数组。
def diag(v, k=0):
x = np.arange(9).reshape((3, 3))
print(x)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]
print(np.diag(x))  # [0 4 8]
print(np.diag(x, k=1))  # [1 5]
print(np.diag(x, k=-1))  # [3 7]

v = [1, 3, 5, 7]
x = np.diag(v)
print(x)
# [[1 0 0 0]
#  [0 3 0 0]
#  [0 0 5 0]
#  [0 0 0 7]]
(f)常数数组
  • full()函数:返回一个常数数组,要设置填充的常数值。

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

    def full(shape, fill_value, dtype=None, order='C'):
    def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):
    
import numpy as np

x = np.full((2,), 7)
print(x)
# [7 7]

x = np.full(2, 7)
print(x)
# [7 7]

x = np.full((2, 7), 7)
print(x)
# [[7 7 7 7 7 7 7]
#  [7 7 7 7 7 7 7]]

x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.full_like(x, 7)
print(y)
# [[7 7 7]
#  [7 7 7]]

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

  • arange()函数:返回给定间隔内的均匀间隔的值,当只有一个参数时,默认从零开始。
  • linspace()函数:返回指定间隔内的等间隔数字。
  • logspace()函数:返回数以对数刻度均匀分布。
  • numpy.random.rand() 返回一个由[0,1)内的随机数组成的数组,可以指定shape。
def arange([start,] stop, [step,], dtype=None): 
def linspace(start, stop, num=50, endpoint=True, retstep=False, 
             dtype=None, axis=0):
def logspace(start, stop, num=50, endpoint=True, base=10.0, 
             dtype=None, axis=0):
def rand(d0, d1, ..., dn): 

4.结构数组

(a)利用字典定义结构np.dtype()
import numpy as np
# 定义一种叫personType的结构
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)]

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

05 数组的属性

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

注:在ndarray中所有元素必须是同一类型,否则会自动向下转换,int->float->str

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

from PIL import Image
img1 = Image.open('test.jpg')
a = np.array(img1)
print(a.shape, a.dtype)
# (959, 959, 3) uint8

猜你喜欢

转载自blog.csdn.net/weixin_41545602/article/details/109175836