numpy介绍

目录

一、numpy概述

  1. Numerical Python,数值的Python,补充了Python语言所欠缺的数值计算能力。
  2. Numpy是其它数据分析及机器学习库的底层库。
  3. Numpy完全标准C语言实现,运行效率充分优化。
  4. Numpy开源免费。

官方文档: https://www.numpy.org

官方中文文档: https://www.numpy.org.cn/

1. numpy历史

  1. 1995年,Numeric,Python语言数值计算扩充。
  2. 2001年,Scipy->Numarray,多维数组运算。
  3. 2005年,Numeric+Numarray->Numpy。
  4. 2006年,Numpy脱离Scipy成为独立的项目。

2. numpy的核心:多维数组

  1. 代码简洁:减少Python代码中的循环。
  2. 底层实现:厚内核©+薄接口(Python),保证性能。

二、numpy基础

1. ndarray数组

用np.ndarray类的对象表示n维数组

import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary))

1)内存中的ndarray对象

元数据(metadata)

存储对目标数组的描述信息,如:dim count、dimensions、dtype、data等。

实际数据

完整的数组数据

将实际数据与元数据分开存放,一方面提高了内存空间的使用效率,另一方面减少对实际数据的访问频率,提高性能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9MMpxi5n-1638019422028)(./img/ndarray_struct.png)]

2)ndarray数组对象的特点

  1. Numpy数组是同质数组,即所有元素的数据类型必须相同
  2. Numpy数组的下标从0开始,最后一个元素的下标为数组长度减1

3)ndarray数组对象的创建

np.array(任何可被解释为Numpy数组的逻辑结构)

import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
print(a)

np.arange(起始值(0),终止值,步长(1))

import numpy as np
a = np.arange(0, 5, 1)
print(a)
b = np.arange(0, 10, 2)
print(b)

np.zeros(数组元素个数, dtype=‘类型’)

import numpy as np
a = np.zeros(10)
print(a)

np.ones(数组元素个数, dtype=‘类型’)

import numpy as np
a = np.ones(10)
print(a)

np.ones_like(类数组)

np.zeros_like(类数组)

import numpy as np
a = np.arange(10).reshape(2, 5)
print(a)
b = np.ones_like(a)
print(b)
c = np.zeros_like(a)
print(c)

4)ndarray对象属性的基本操作

**数组的维度:**np.ndarray.shape

import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary), ary, ary.shape)
#二维数组
ary = np.array([
    [1,2,3,4],
    [5,6,7,8]
])
print(type(ary), ary, ary.shape)

**元素的类型:**np.ndarray.dtype

import numpy as np
ary = np.array([1, 2, 3, 4, 5, 6])
print(type(ary), ary, ary.dtype)
#转换ary元素的类型
b = ary.astype(float)
print(type(b), b, b.dtype)
#转换ary元素的类型
c = ary.astype(str)
print(type(c), c, c.dtype)

**数组元素的个数:**np.ndarray.size

import numpy as np
ary = np.array([
    [1,2,3,4],
    [5,6,7,8]
])
#观察维度,size,len的区别
print(ary.shape, ary.size, len(ary))

5)ndarray对象的dtype属性的值

Numpy的内部基本数据类型

类型名类型表示符类型代码
布尔型bool_?
有符号整数型int8(-128~127)/int16/int32/int64i1/i2/i4/i8
无符号整数型uint8(0~255)/uint16/uint32/uint64u1/u2/u4/u8
浮点型float16/float32/float64f2/f4/f8
复数型complex64/complex128C8/c16/c32
字节串型bytes_(兼容:Python字节)S#
字符串型str_(兼容:Python unicode)4字节‘U#’
日期时间np.datetime64M8[Y] M8[M]
M8[D] M8[h]
M8[m] M8[s]

自定义复合类型

若希望ndarray中存储对象类型,numpy建议使用元组存储对象的属性字段值,然后把元组添加到ndarray中,ndarray提供了语法方便的处理这些数据。

# 自定义复合类型
import numpy as np

data=[
(‘zs’, [90, 80, 85], 15),
(‘ls’, [92, 81, 83], 16),
(‘ww’, [95, 85, 95], 15)
]

第一种设置dtype的方式

a = np.array(data, dtype='U3, 3int32, int32')
print(a)
print(a[0]['f0'], ":", a[1]['f1'])

第二种设置dtype的方式

b = np.array(data, dtype=[
    ('name', 'str_', 2),
    ('scores', 'int32', 3),
    ('ages', 'int32', 1)
])
print(b[0]['name'], ":", b[0]['scores'])

第三种设置dtype的方式

c = np.array(data, dtype={
    'names': ['name', 'scores', 'ages'],
    'formats': ['U3', '3int32', 'int32']
})
print(c[0]['name'], ":", c[0]['scores'], ":", c.itemsize)

第四种设置dtype的方式

d = np.array(data, dtype={
    'names': ('U3', 0),  # 偏移位置为0字节,占用12个字节
  'scores': ('3int32', 16),  # 空4个字节,偏移到16字节位置
    'ages': ('int32', 28)  # 偏移到16字节位置
})
print(d[0]['names'], d[0]['scores'], d.itemsize)

Numpy的日期时间类型

类型名类型表示符类型代码
日期时间np.datetime64M8[Y] M8[M] M8[D] M8[h] M8[m] M8[s]

测试日期类型数组

f = np.array(['2011', '2012-01-01', 
              '2013-01-01 01:01:01','2011-02-01'])
f = f.astype('M8[D]')
f = f.astype('int32')
print(f[3]-f[0])

复数类型的矩阵

a = np.array([[1 + 1j, 2 + 4j, 3 + 7j],
              [4 + 2j, 5 + 5j, 6 + 8j],
              [7 + 3j, 8 + 6j, 9 + 9j]])
print(a.T)
for x in a.flat:
    print(x.imag)

字节序前缀,用于多字节整数和字符串:
</>/[=]分别表示小端/大端/硬件字节序。

类型字符码格式

<字节序前缀><维度><类型><字节数或字符数>

3i4释义
3i4大端字节序,3个元素的一维数组,每个元素都是整型,每个整型元素占4个字节。
<(2,3)u8小端字节序,6个元素2行3列的二维数组,每个元素都是无符号整型,每个无符号整型元素占8个字节。
U7包含7个字符的Unicode字符串,每个字符占4个字节,采用默认字节序。

房价数据表示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zIauakIe-1638019422030)(./img/beijing_house_data.png)]

import numpy as np

data = [(‘宝星华庭一层带花园’, ‘4室1厅’, 298.79, 2598, 86951),
(‘绿地花园’, ‘3室2厅’, 154.62, 1000, 64675),
(‘沁园公寓’, ‘3室2厅’, 177.36, 1200, 67659)]

ary = np.array(data, dtype={
‘names’:[‘title’, ‘houseType’,
‘square’, ‘totalPrice’, ‘unitPrice’],
‘formats’:[‘20U’, ‘10U’, ‘f8’, ‘f8’, ‘f8’]
})

print(ary)
print(ary[‘totalPrice’])

day02

6) ndarray数组对象的维度操作

视图变维(数据共享): reshape() 与 ravel()

import numpy as np
a = np.arange(1, 9)
print(a)        # [1 2 3 4 5 6 7 8]
b = a.reshape(2, 4)    #视图变维  : 变为2行4列的二维数组
print(b)
c = b.reshape(2, 2, 2) #视图变维    变为2页2行2列的三维数组
print(c)
d = c.ravel()          #视图变维    变为1维数组
print(d)

**复制变维(数据独立):**flatten()

e = c.flatten()
print(e)
a += 10
print(a, e, sep='\n')

直接变维:直接改变原数组对象的维度

a.shape = (2, 4)
print(a)
a.resize(2, 2, 2)
print(a)

7) 数组元素索引(下标)

数组对象[…, 页号, 行号, 列号]

下标从0开始,到数组len-1结束。

import numpy as np
a = np.array([[[1, 2],
               [3, 4]],
              [[5, 6],
               [7, 8]]])
print(a, a.shape)
print(a[0])
print(a[0][0])
print(a[0][0][0])
print(a[0, 0, 0])
for i in range(a.shape[0]):
    for j in range(a.shape[1]):
        for k in range(a.shape[2]):
            print(a[i, j, k])

8) ndarray数组切片操作

#数组对象切片的参数设置与列表切面参数类似
#  步长+:默认切从首到尾
#  步长-:默认切从尾到首
数组对象[起始位置:终止位置:步长, ...]
#默认位置步长:1
import numpy as np
a = np.arange(1, 10)
print(a)  # 1 2 3 4 5 6 7 8 9
print(a[:3])  # 1 2 3
print(a[3:6])   # 4 5 6
print(a[6:])  # 7 8 9
print(a[::-1])  # 9 8 7 6 5 4 3 2 1
print(a[:-4:-1])  # 9 8 7
print(a[-4:-7:-1])  # 6 5 4
print(a[-7::-1])  # 3 2 1
print(a[::])  # 1 2 3 4 5 6 7 8 9
print(a[:])  # 1 2 3 4 5 6 7 8 9
print(a[::3])  # 1 4 7
print(a[1::3])  # 2 5 8
print(a[2::3])  # 3 6 9

多维数组的切片操作

import numpy as np
a = np.arange(1, 28)
a.resize(3,3,3)
print(a)
#切出1页 
print(a[1, :, :])        
#切出所有页的1行
print(a[:, 1, :])        
#切出0页的所有行的第1列
print(a[0, :, 1])        

9) ndarray数组的运算

算术运算

# 算术运算符
+    -    *    /     //     %     **    @ (矩阵乘法)
# 复合赋值算术运算
+=    -=    *=    /=     //=     %=     **=

示例:

import numpy as np
a = np.arange(1, 10).reshape(3, 3)
b = np.arange(9, 0, -1).reshape(3, 3)
print(a + b)  # 同等维度的数组内部对应位置的数据元素进行运算
print(a - b)
print(a * b)
print(a ** b)
print(a @ b)
c = a * 2   # 对全体数据进行运算
print(c)
print(a ** 2)


数组乘法运算

数组有两种乘法运算: 数组乘积运算和矩阵点乘

数组乘积运算 C = A × B C = A × B C = A × B C = A × B C = A \times B C=A×B C=A×BC=A×BC=A×B

矩阵点乘运算 C = A ⋅ B C = A ⋅ B C = A ⋅ B C = A ⋅ B C = A \cdot B C=A⋅B C=ABC=ABC=AB

数组乘积运算

Numpy 中用 * 运算符实现

要求数组的维度必须相等

矩阵点乘运算

矩阵点乘只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义

如:
KaTeX parse error: Undefined control sequence: \̲ at position 82: …[\begin{array} \̲̲̲ ̲a_{11}&a_{12}…

KaTeX parse error: Undefined control sequence: \̲ at position 82: …[\begin{array} \̲̲̲ ̲b_{11}&b_{12}…

KaTeX parse error: Undefined control sequence: \̲ at position 82: …[\begin{array} \̲̲̲ ̲a_{11}b_{11}+…

示例:

import numpy as np
a = np.array([[1, 2, 3],
              [4, 5, 6]])
b = np.array([[10, 20],
              [30, 40],
              [50, 60]])
c = a @ b
print(c)
#  [[220 280]
#   [490 640]]

示例:

比较运算

<      <=     >      >=     ==      != 

示例

import numpy as np
a = np.arange(1, 10).reshape(3, 3)
b = np.arange(9, 0, -1).reshape(3, 3)
print(a > b)
print(a > 3)
print(a == 5)

10) ndarray数组的掩码操作

布尔掩码

布尔掩码是用索引数组中对应位置的布尔值来挑选原数组中的元素,对应位置为True 的选取,为False 时则丢弃;返回选取元素的一维数组。

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
mask = [False, True, True, False, True, False, True, False, False]
print(a[mask])  # array([2, 3, 5, 7])


       

索引掩码是用索引的长度生成一个新的数组,数组中的元素采用索引列表中的数字在原列表中取数据再放入索引中对应的位置。

import numpy as np
a = np.array(['Mi', 'Huawei', 'Apple', 'Oppo', 'Vivo'])
indices = [0, 3, 4, 1, 2]
print(a[indices])

11) 多维数组的组合与拆分

二维数组的操作

合并

import numpy as np
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(7, 13).reshape(2, 3)
# 水平方向合并
c = np.hstack((a, b))
print(c)
# 垂直方向合并
c = np.vstack((a, b))
print(c)


         

拆分

import numpy as np
c = np.array([[ 1,  2,  3],
              [ 4,  5,  6],
              [ 7,  8,  9],
              [10, 11, 12]])
# 垂直方向完成拆分操作,生成两个数组
d, e = np.vsplit(c, 2)
print(d, e, sep='\n')
# 水平方向完成拆分操作,生成三个数组
x, y, z = np.hsplit(c, 3)
print(x, y, z, sep='\n')

合并,拆分通用函数

np.concatenate((a, b), axis=0)
# 通过给出的数组与要拆分的份数,按照某个方向进行拆分,axis的取值同上
np.split(c, 2, axis=0)

axis 的取值

# 通过axis作为关键字参数指定组合的方向,取值如下:
# 二维数组:
#    0: 垂直方向(行)
#    1: 水平方向(列)
# 三维数组:
#    0: 深度方向(页)
#    1: 垂直方向(行)
#    2: 水平方向(列)

二维数组通用函数操作操作

import numpy as np
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(7, 13).reshape(2, 3)
c = np.concatenate((a, b), axis=0)  # 垂直方向
print(c)
c = np.concatenate((a, b), axis=1)  # 水平方向
print(c)
d = np.split(c, 2, axis=0)  # 垂直方向
print(d)
d = np.split(c, 2, axis=1)  # 水平方向
print(d)

三维数组的操作

合并

import numpy as np
a = np.arange(1, 7).reshape(1, 2, 3)
b = np.arange(7, 13).reshape(1, 2, 3)

# 合并
c = np.concatenate((a, b), axis=0)  # 深度方向
print(c)
d = np.concatenate((a, b), axis=1)  # 垂直方向
print(d)
e = np.concatenate((a, b), axis=2)  # 水平方向
print(e)


              

拆分

import numpy as np
c = np.array([[[ 1,  2,  3],
               [ 4,  5,  6]],
              [[ 7,  8,  9],
               [10, 11, 12]]])
# 拆分
x, y = np.split(c, 2, axis=0)  # 深度方向
print(x, y, sep='\n')
x, y = np.split(c, 2, axis=1)  # 垂直方向
print(x, y, sep='\n')
x, y, z = np.split(c, 3, axis=2)  # 水平方向
print(x, y, z, sep='\n')

长度不等的数组组合:

numpy.pad(array,   # 原数组
          pad_width=(前填充数, 后填充数), 
          mode='constant', constant_values=填充值)


示例

import numpy as np
a = np.array([1,2,3,4,5])
b = np.array([1,2,3,4])
# 填充b数组使其长度与a相同
b = np.pad(b, pad_width=(0, 1), mode='constant', constant_values=-1)
print(b)
# 垂直方向完成组合操作,生成新数组
c = np.vstack((a, b))
print(c)

简单的一维数组组合方案

a = np.arange(1,9)         # [1, 2, 3, 4, 5, 6, 7, 8]
b = np.arange(9,17)        # [9,10,11,12,13,14,15,16]
#把两个数组摞在一起成两行
c = np.row_stack((a, b))
print(c)
#把两个数组组合在一起成两列
d = np.column_stack((a, b))
print(d)


                  

https://numpy.org/doc/stable/reference/generated/numpy.split.html

https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html

12)ndarray类的其他属性

  • shape - 维度

  • dtype - 元素类型

  • size - 元素数量

  • ndim - 维数,len(shape)

  • itemsize - 元素字节数

  • nbytes - 总字节数 = size x itemsize

  • real - 复数数组的实部数组

  • imag - 复数数组的虚部数组

  • T - 数组对象的转置视图

  • flat - 扁平迭代器

import numpy as np
a = np.array([[1 + 1j, 2 + 4j, 3 + 7j],
              [4 + 2j, 5 + 5j, 6 + 8j],
              [7 + 3j, 8 + 6j, 9 + 9j]])
print(a.shape)
print(a.dtype)
print(a.ndim)
print(a.size)
print(a.itemsize)
print(a.nbytes)
print(a.real, a.imag, sep='\n')
print(a.T)
print([elem for elem in a.flat])
b = a.tolist()  # 转为列表
print(b)

2. numpy文件操作

numpy加载文本文件

numpy提供了函数用于加载逻辑上可被解释为二维数组的文本文件,格式如下:

数据项1 <分隔符> 数据项2 <分隔符> ... <分隔符> 数据项n
例如:
AA,AA,AA,AA,AA
BB,BB,BB,BB,BB
...
或:
AA:AA:AA:AA:AA
BB:BB:BB:BB:BB
...


调用numpy.loadtxt()函数可以直接读取该文件并且获取ndarray数组对象:

加载文本文件

numpy提供了loadtxt()函数用于解析文本为ndarray

函数调用格式

numpy.loadtxt(
    fname,           # 文件路径
    dtype=float,     # 指定返回每一列数组中元素的类型
    delimiter=None,  # 分隔符(缺省值为空格) 
    converters=None  # 转换器函数字典{1: func1, 2:func2}
    skiprows=0,      # 跳过行数,默认0,不跳过
    usecols=None,    # 列序列(1, 3)读取1、3两列 
    unpack=False,    # 是否按列拆包,是否单独拆分变量返回
    encoding=None,   # 编码.
    ...
)
# 返回 NDArray


loadtxt 参数详解

函数参数参数解释
fname文件路径
dtype每列数据的数据类型。认为 float
delimiter分隔符(缺省值为空格)
converters转换器函数字典{1: func1, 2:func2}
skiprows过行数,默认0,不跳过
usecols选择读取文件中的某些列。设置为相应列的索引列表。
unpack是否按列拆包,是否单独拆分变量返回
encoding编码。

例如:

import numpy as np

data = np.loadtxt("CustomerSurvival.csv",
                  skiprows=1,
                  delimiter=',')
print(data)

保存为文本文件

numpy提供了savetxt()函数用于将NDArray转为文本文件

函数调用格式

numpy.to_savetxtcsv(
    fname=None,
    X,
    fmt='%.18e',
    delimiter=' ',
    newline='\n',
    encoding=None
    ...
)

savetext()参数详解

方法参数参数解释
fname文件路径
XNDArray数组
fmt浮点数的输出格式,默认’%.18e’
delimiter分隔符,默认使用空格分隔(’ ')
newline换行符,默认:’\n’
encoding编码(默认UTF-8)。

示例:

import numpy as np

data = np.arange(1, 10).reshape(3, 3)
print(data)
np.savetxt('temp.txt', data, '%d')

                
posted @ 2022-11-21 18:53  TwcatL_tree  阅读(1)  评论(0编辑  收藏  举报