Files
ailearning/docs/da/032.md
2020-10-19 21:08:55 +08:00

626 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数组类型
In [1]:
```py
from numpy import *
```
之前已经看过整数数组和布尔数组,除此之外还有浮点数数组和复数数组。
## 复数数组
产生一个复数数组:
In [2]:
```py
a = array([1 + 1j, 2, 3, 4])
```
**Python**会自动判断数组的类型:
In [3]:
```py
a.dtype
```
Out[3]:
```py
dtype('complex128')
```
对于复数我们可以查看它的实部和虚部:
In [4]:
```py
a.real
```
Out[4]:
```py
array([ 1., 2., 3., 4.])
```
In [5]:
```py
a.imag
```
Out[5]:
```py
array([ 1., 0., 0., 0.])
```
还可以设置它们的值:
In [6]:
```py
a.imag = [1,2,3,4]
```
查看 `a`
In [7]:
```py
a
```
Out[7]:
```py
array([ 1.+1.j, 2.+2.j, 3.+3.j, 4.+4.j])
```
查看复共轭:
In [8]:
```py
a.conj()
```
Out[8]:
```py
array([ 1.-1.j, 2.-2.j, 3.-3.j, 4.-4.j])
```
事实上,这些属性方法可以用在浮点数或者整数数组上:
In [9]:
```py
a = array([0.,1,2,3])
a.dtype
```
Out[9]:
```py
dtype('float64')
```
In [10]:
```py
a.real
```
Out[10]:
```py
array([ 0., 1., 2., 3.])
```
In [11]:
```py
a.imag
```
Out[11]:
```py
array([ 0., 0., 0., 0.])
```
In [12]:
```py
a.conj()
```
Out[12]:
```py
array([ 0., 1., 2., 3.])
```
但这里,虚部是只读的,并不能修改它的值:
In [13]:
```py
# 会报错
a.imag = [1,2,3,4]
```
```py
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-3db28f506ec9> in <module>()
1 # 会报错
----> 2 a.imag = [1,2,3,4]
TypeError: array does not have imaginary part to set
```
## 指定数组类型
之前已经知道,构建数组的时候,数组会根据传入的内容自动判断类型:
In [14]:
```py
a = array([0,1.0,2,3])
```
对于浮点数,默认为双精度:
In [15]:
```py
a.dtype
```
Out[15]:
```py
dtype('float64')
```
查看所用字节(`8 bytes * 4`
In [16]:
```py
a.nbytes
```
Out[16]:
```py
32
```
当然,我们也可以在构建的时候指定类型:
In [17]:
```py
a = array([0,1.0,2,3],
dtype=float32)
```
此时类型为单精度浮点数:
In [18]:
```py
a.dtype
```
Out[18]:
```py
dtype('float32')
```
查看所用字节(`4 bytes * 4`
In [19]:
```py
a.nbytes
```
Out[19]:
```py
16
```
除此之外,还可以指定有无符号,例如无符号整数:
In [20]:
```py
a = array([0,1,2,3],
dtype=uint8)
a.dtype
```
Out[20]:
```py
dtype('uint8')
```
`uint8` 只使用一个字节,表示 `0``255` 的整数。
还可以从二进制数据中读取。
先写入二进制数据:
In [21]:
```py
a = array([102,111,212],
dtype=uint8)
a.tofile('foo.dat')
```
从数据中读入,要指定类型:
In [22]:
```py
b = frombuffer('foo',
dtype=uint8)
b
```
Out[22]:
```py
array([102, 111, 111], dtype=uint8)
```
清理数据文件:
In [23]:
```py
import os
os.remove('foo.dat')
```
`0-255` 的数字可以表示ASCⅡ码我们可以用 ord 函数来查看字符的ASCⅡ码值
In [24]:
```py
ord('f')
```
Out[24]:
```py
102
```
In [25]:
```py
ord('S')
```
Out[25]:
```py
83
```
## Numpy 类型
具体如下:
| 基本类型 | 可用的**Numpy**类型 | 备注 |
| --- | --- | --- |
| 布尔型 | `bool` | 占1个字节 |
| 整型 | `int8, int16, int32, int64, int128, int` | `int` 跟**C**语言中的 `long` 一样大 |
| 无符号整型 | `uint8, uint16, uint32, uint64, uint128, uint` | `uint` 跟**C**语言中的 `unsigned long` 一样大 |
| 浮点数 | `float16, float32, float64, float, longfloat` | 默认为双精度 `float64` `longfloat` 精度大小与系统有关 |
| 复数 | `complex64, complex128, complex, longcomplex` | 默认为 `complex128` ,即实部虚部都为双精度 |
| 字符串 | `string, unicode` | 可以使用 `dtype=S4` 表示一个4字节字符串的数组 |
| 对象 | `object` | 数组中可以使用任意值 |
| Records | `void` | |
| 时间 | `datetime64, timedelta64` |
任意类型的数组:
In [26]:
```py
a = array([1,1.2,'hello', [10,20,30]],
dtype=object)
```
乘法:
In [27]:
```py
a * 2
```
Out[27]:
```py
array([2, 2.4, 'hellohello', [10, 20, 30, 10, 20, 30]], dtype=object)
```
## 类型转换
转换数组的类型:
In [28]:
```py
a = array([1.5, -3],
dtype=float32)
a
```
Out[28]:
```py
array([ 1.5, -3\. ], dtype=float32)
```
### asarray 函数
使用 `asarray` 函数:
In [29]:
```py
asarray(a, dtype=float64)
```
Out[29]:
```py
array([ 1.5, -3\. ])
```
In [30]:
```py
asarray(a, dtype=uint8)
```
Out[30]:
```py
array([ 1, 253], dtype=uint8)
```
`asarray` 不会修改原来数组的值:
In [31]:
```py
a
```
Out[31]:
```py
array([ 1.5, -3\. ], dtype=float32)
```
但当类型相同的时候,`asarray` 并不会产生新的对象,而是使用同一个引用:
In [32]:
```py
b = asarray(a, dtype=float32)
```
In [33]:
```py
b is a
```
Out[33]:
```py
True
```
这么做的好处在与,`asarray` 不仅可以作用于数组,还可以将其他类型转化为数组。
有些时候为了保证我们的输入值是数组,我们需要将其使用 `asarray` 转化,当它已经是数组的时候,并不会产生新的对象,这样保证了效率。
In [34]:
```py
asarray([1,2,3,4])
```
Out[34]:
```py
array([1, 2, 3, 4])
```
### astype 方法
`astype` 方法返回一个新数组:
In [35]:
```py
a.astype(float64)
```
Out[35]:
```py
array([ 1.5, -3\. ])
```
In [36]:
```py
a.astype(uint8)
```
Out[36]:
```py
array([ 1, 253], dtype=uint8)
```
astype也不会改变原来数组的值
In [37]:
```py
a
```
Out[37]:
```py
array([ 1.5, -3\. ], dtype=float32)
```
另外,`astype` 总是返回原来数组的一份复制,即使转换的类型是相同的:
In [38]:
```py
b = a.astype(float32)
print a
print b
```
```py
[ 1.5 -3\. ]
[ 1.5 -3\. ]
```
In [39]:
```py
a is b
```
Out[39]:
```py
False
```
### view 方法
In [40]:
```py
a = array((1,2,3,4), dtype=int32)
a
```
Out[40]:
```py
array([1, 2, 3, 4])
```
`view` 会将 `a` 在内存中的表示看成是 `uint8` 进行解析:
In [41]:
```py
b = a.view(uint8)
b
```
Out[41]:
```py
array([1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0], dtype=uint8)
```
In [42]:
```py
a[0] = 2**30
a
```
Out[42]:
```py
array([1073741824, 2, 3, 4])
```
修改 `a` 会修改 `b` 的值,因为共用一块内存:
In [43]:
```py
b
```
Out[43]:
```py
array([ 0, 0, 0, 64, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0], dtype=uint8)
```