[TOC]
> 一个ndarray数组,其中的元素类型必须一致。后面的例子默认已经导入了numpy了`import numpy as np`。在numpy中多维的体现可以从 `[` 的个数体现,一个表示一维数组,两个表示二维数组,三个表示三维数组。
# 一、创建n维数组
## 1、Python序列创建
通过Python内置序列(列表、元组、迭代器等)生成。`dtype`指定元素类型。**注意**:这里有两种形式的 `dtype`指定,`dtype`的类型范围可能会超出最大范围,比如 `int8` 表示的范围为`-128 ~ 127`,所以要特别注意,常用`dtype`类型见后面。
```
In [4]: np.array([1,2,3,4,5], dtype=np.int8)
Out[4]: array([1, 2, 3, 4, 5], dtype='i1')
```
```
In [5]: np.array([[1,2], [3,4]])
In [5]:
array([[1, 2],
[3, 4]])
```
```
In [6]: np.array(range(5))
Out[6]: array([0, 1, 2, 3, 4])
```
## 2、numpy函数创建
- 一维数组
```
In [101]: np.arange(10)
Out[101]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
- 全为0的数组
```
In [7]: np.zeros((3, 3))
Out[7]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
```
- 全为1的数组
```
In [8]: np.ones((3, 3))
Out[8]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
```
- 指定具体的数
```
In [9]: np.full((3, 3), 7)
Out[9]:
array([[7, 7, 7],
[7, 7, 7],
[7, 7, 7]])
```
- 单位矩阵
```
# eye 和 identity 功能相同, 用法也相同
In [10]: np.eye(3, dtype=np.float)
Out[10]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
In [135]: np.identity(3, dtype=np.int64)
Out[135]:
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
```
- 随机值
```
In [11]: np.random.random((3, 3))
Out[11]:
array([[0.99663102, 0.93404837, 0.74045542],
[0.96095057, 0.47071128, 0.93326441],
[0.04164389, 0.87707493, 0.06682718]])
In [12]: np.random.random_sample((3, 3))
Out[12]:
array([[0.45564524, 0.79054459, 0.35354065],
[0.85432253, 0.31309465, 0.91109144],
[0.11545255, 0.87425802, 0.29299949]])
```
- 未初始化的值
`uninitialized`的值,速度比`zeros`快,因为它不需要给元素赋值,但是生成的值是随机的,所以要手动赋值,使用时也要更加小心。
```
In [77]: np.empty(8, dtype=np.int)
Out[77]:
array([ 140394674920672, 94236150077088, 1106911206096216771,
140394115432776, 140394113101264, 1801088188859453026,
140393510918704, 140394113101296, 80])
```
- 使用已经存在的数组的 `shape、dtype` 初始化
```
In [110]: arr=np.array((3, 3), dtype=np.int64)
arr_new=np.full_like(arr, 9)
arr_new=np.ones_like(arr)
arr_new=np.zeros_like(arr)
arr_new=np.empty_like(arr)
```
# 二、numpy属性
## 1、常用属性
```
arr = np.ones((3, 3), dtype=int)
arr.dtype # dtype('float64')
arr.shape # (3, 3) 3行3列二维数组
arr.ndim # 2 最小维度
```
## 2、dtype类型
类型 | 类型码| 描述
:-: | :-: | :-:
`int8, uint8` | `i1, u1`| 有符号和无符号8位(1字节)整数类型
`int16, uint16` |`i2, u2`| 有符号和无符号16位整数类型
`int32, uint32` |`i4, u4`| 有符号和无符号32位整数类型
`int64, uint64` |`i8, u8`| 有符号和无符号64位整数类型
`float16` | `f2` | 半精度浮点类型
`float32` | `f4 or f`| 标准精度浮点。与C的 `float` 兼容
`float64` |`f8 or d`| 标准双精度浮点。与C的 `double` 和 Python 的 `folat` 对象兼容
`float128` | `f16 or g`| 扩展精度浮点
`complex64, complex128, complex256` |`c8, c16, c32`| 分别使用两个32, 64, 128位浮点表示的复数
`bool` | `?` | 布尔值, 存储 `True` 和 `False`
`object` | `O` | Python对象类型
`string_` | `S` | 定长字符串类型(每字符一字节),例如为了生成长度为10的字符窜,使用`'S10'`
`unicode_` | `f16 or g` | 扩展精度浮点(字节数依赖平台),同 string_ 有相同的语义规范,例如`'U10' `
# 三、索引和切片
## 1、一维数组
- 一维数组索引切片和列表的索引和切片类似。
```
In [359]: a = np.array([1,2,3,4,5,6])
In [360]: a[2:4]
Out[360]: array([3, 4])
In [361]: a[0]
Out[361]: 1
```
## 2、 多维数组
### a. 下标索引
```
In [362]: a = np.arange(12).reshape(3, 4)
In [363]: a
Out[363]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 两种方式获取一个位置的元素
In [364]: a[0][1] # 先获取第一维,在第一维的基础上获取第二维。
Out[364]: 1
In [365]: a[0, 1] # 一次性指定具体位置。
Out[365]: 1
# 两种方式获取一个位置的元素
In [366]: a = np.arange(12).reshape(2, 2, 3)
In [367]: a
Out[367]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [368]: a[0][1][1] # 先获取第一维,在第一维的基础上获取第二维。
Out[368]: 4
In [369]: a[0, 1, 1] # 一次性指定具体位置。
Out[369]: 4
```
### b. 切片索引
在多维数组下标索引的前提下,针对每一维的数据做切片,切片的原理和Python内置列表的切片一样。
```
In [370]: a = np.arange(12).reshape(2, 2, 3)
In [371]: a
Out[371]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
# 注意切片不能改变原来的结构,原来是列表,切出来还是列表,下标索引的话得到的是一个元素, 所以下面的两个切片得到的结果分别是一维数组、二维数组。
In [374]: a[1, 1, 1:]
Out[374]: array([10, 11])
In [375]: a[:1, 1:, 1]
Out[375]: array([[4]])
```
### c. 布尔索引
```
In [377]: a = np.arange(12).reshape(3, 4)
In [378]: a
Out[378]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 构建一个布尔型的数组
In [405]: b = np.array([1, 2, 3])
In [406]: b == 2
Out[406]: array([False, True, False])
# 根据布尔型数组索引
In [407]: a[b==2]
Out[407]: array([[4, 5, 6, 7]])
```
### d. 下标、切片、布尔混合使用
```
In [409]: a = np.arange(12).reshape(2, 2, 3)
In [410]: a
Out[410]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [414]: a[[False, True], :1, 2]
Out[414]: array([[8]])
```
### e. 花式索引
花式索引相当于下标索引,只不过这时下标是列表。
```
In [429]: a = np.arange(12).reshape(4, 3)
In [430]: a
Out[430]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [431]: a[[0,1]]
Out[431]:
array([[0, 1, 2],
[3, 4, 5]])
```
# 四、numpy操作
## 1、基本操作
- 显示转换值类型
将 `a` 的值类型转换成float, `b` 是一个全新的数组,值类型是float
```
In [304]: a = np.array([1,2,3], dtype=np.int8)
In [306]: b = a.astype(np.float)
```
- 广播
将标量赋值给一个数组的切片,此时会将该值自动赋值到整个切片范围。
```
In [343]: a=np.array([1,2,3,4])
In [344]: a[2:4] = 8
In [345]: a
Out[345]: array([1, 2, 8, 8])
**注意**:对列表的切片是对原数组的复制,而数组的切片是对原始数据操作。
```
- 复制
`a` 和 `b` 是两个不同的数组,有不同的内存地址
```
a = np.array([1,2,3])
b = a.copy()
```
- 数学操作
numpy 的数学运算是针对有相同形状的数组进行的,一次将对应位置的数运算。多维数组的操作也是整体进行的
```
In [436]: x = np.array([[1,2],[3,4]], dtype=np.float)
In [437]: y = np.array([[5,6],[7,8]], dtype=np.float)
x + y
x - y
x * y
x / y
In [442]: x + 10
Out[442]:
array([[11., 12.],
[13., 14.]])
```