Python数据分析基础教程:NumPy学习指南 第一章 NumPy基础

目录

第一章    NumPy基础

1.1    NumPy数组对象

关键字:array、arange、ndarray、type、dtype、shape、下标

1.2    NumPy数据类型

array、arange指定函数类型

复数的写法及转化规则

1.3    数组元素所占的字节数 a.dtype.itemsize

1.4    字符编码:不推荐使用

1.5    numpy完整的数据类型列表

1.6    定义自己的数据类型

dtype类的属性

1.7    创建自定义数据类型

1.8    一维数组的索引和切片&利用步长-1来翻转数组

1.9   多维数组的切片和索引

reshape创建多维数组

数组元素索引的表示方式a[1,2] or/and a[1][2] 以及列表元素索引

用省略号'...'来表示遍历剩下的维度

使用-1进行多维数组的翻转

1.10    改变数组的维度

使用reshape将数组展平

将数组展平b.ravel()、b.flatten():维度变为(长度,)

用元组设置维度:b.shape=(6,4) 等价于 b=b.reshape(6,4)

矩阵转置 b.transpose() 或者 b.T

b.resize((2,12))功能和reshape(2,12)一样,不同点是,resize会直接改变b的值

1.11    数组的组合(合并)

水平组合:np.hstack((a,b))或者np.concatenate((a,b), axis=1)

垂直组合:np.vstack((a,b))或者 np.concatenate((a,b), axis=0)

深度组合 :np.dstack((a,b))

列组合:column_stack

行组合 row_stack

1.12    数组分割

水平分割 np.split(a,3)分成3份

垂直分割:np.vsplit(a,3)

深度分割 np.dsplit(a, 3)

1.13    数组的属性

维数:b.ndim

元素个数:b.size

数组每个元素在内存中所占字节数:b.itemsize

数组每个元素的数据类型:b.dtype

数组所有元素所占存储空间:b.nbytes 其实就是size*itemsize 

转置:b.T或者b.transpose()

复数实部:b.real

复数虚部:b.imag

如果数组中包含复数元素,则其数据类型自动变为复数型

flat属性 :允许我们像遍历一维数组一样去遍历多维数组

1.14    数组的转换:将数组转换为Python列表

转变数组元素的数据类型: b.astype(int)


第一章    NumPy基础

1.1    NumPy数组对象

NumPy中的 ndarray 是一个多维数组对象,该对象由两部分组成:

  • 实际的数据
  • 描述这些数据的元数据。

大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据

关键字:array、arange、ndarray、type、dtype、shape、下标

import numpy as np

a=np.arange(5)
print(type(a))          # type 是原生Python自带的
print(a.dtype)          # dtype是numpy的,原生Python不含有这个函数

out:

<class 'numpy.ndarray'>  # a的类型是ndarray
int64                    # a的数据的类型是64位的整型

NumPy数组一般是同质的(但有一种特殊的数组类型例外,它是异质的),即数组中的所有元素类型必须是一致的。这样有一个好处:如果我们知道数组中的元素均为同一类型,该数组所需的存储空间就很容易确定下来。

NumPy数组的下标也是从0开始的。

print(a)
print(a[0])
print(a.shape)

out:

[0 1 2 3 4]
0

(5,)

使用array创建数组,参数必须是list

m=np.array([np.arange(2),np.arange(2)])  # 参数是列表,列表的每一个元素又是一个数组
print(m)
print(m.shape)
print(m[0][1])
print(m[1][0])  # 指定数组中的某个元素


out:

[[0 1]
 [0 1]]

(2, 2)      # 维度输出属性是tuple
1
0

1.2    NumPy数据类型

Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需求,因此NumPy添加了很多其他的数据类型。在实际应用中,我们需要不同精度的数据类型,它们占用的内存空间也是不同的。在NumPy中,大部分数据类型名是以数字结尾的,这个数字表示其在内存中占用的位数。下面的表格(整理自NumPy用户手册)列出了NumPy中支持的数据类型。这些类型是仅仅numpy的(除了bool),原生Python不含有这些类型。

每一种数据类型均有对应的类型转换函数:函数名就是它的类型名

a = np.array([1,2])
np.float16(a)       # float16是numpy的类型,所以前面必须加np

out:

array([1., 2.], dtype=float16)

array、arange指定函数类型

在NumPy中,许多函数的参数中可以指定数据类型,通常这个参数是可选的

a=np.arange(7, dtype=np.float16)        # 任何时候数据类型前不要忘记加np
print(a)
b=np.array([0,1,2,3,4], dtype=np.uint16)
print(b)

out:

[0. 1. 2. 3. 4. 5. 6.]
[0 1 2 3 4]

复数的写法及转化规则

复数不能转化为整数或浮点数。整数或浮点数可以转化为复数

a = 3+4j
print(type(a))
b = np.complex(3+4j)
print(type(b))
c = np.complex64(3+4j)
print(type(c))
print(c.dtype)

out:

<class 'complex'>
<class 'complex'>         # 从这里不难看出np.complex和原生的Python自带complex函数意义一样
<class 'numpy.complex64'>
complex64
int(a)
int(b)
out:

TypeError: can't convert complex to int
TypeError: can't convert complex to int


不同点来了,使用np.complex64或np.complex128或np.complex256生成的复数是直接可以变为整型和浮点型的,就是直接取它的实部。但是会有警告产生!!!

np.int8(c) 或 int(c) 或 np.int(c)结果都是:

警告:/home/wu/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:9: ComplexWarning: Casting complex values to real discards the imaginary part
  if __name__ == '__main__':
结果:
  3 

浮点数也是这样:
np.float16(c) 或 float(c) 或 np.folat(c)
警告:/home/wu/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: ComplexWarning: Casting complex values to real discards the imaginary part

结果:3.0


总结:当复数是手写的如:3+4j 类型或者 由complex(3+4j)生成的或由 np.complex(3+4j)生成的类型时 都不能直接转化为整型或浮点型。只由使用np.complex64(3+4j)或np.complex128(3+4j)或np.complex256(3+4j)生成时才能转化为对应的整形或浮点型。



1.3    数组元素所占的字节数 a.dtype.itemsize

a=np.arange(7, dtype=np.float16)
a.dtype.itemsize

out:

2 # 数组a中的每个元素在内存中占两个字节

1.4    字符编码:不推荐使用

NumPy可以使用字符编码来表示数据类型,这是为了兼容NumPy的前身Numeric。我不推荐使用字符编码,但有时会用到,因此下面还是列出了字符编码的对应表。读者应该优先使用 dtype对象来明确表示数据类型,而不是这些字符编码

a=np.arange(7, dtype='f')
a
out:
array([0., 1., 2., 3., 4., 5., 6.], dtype=float32)



b=np.arange(7, dtype='D')
b

out:
array([0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j])

1.5    numpy完整的数据类型列表

np.sctypeDict.keys()

out:

dict_keys(['?', 0, 'byte', 'b', 1, 'ubyte', 'B', 2, 'short', 'h', 3, 'ushort', 'H', 4, 'i', 5, 'uint', 'I', 6, 'intp', 'p', 7, 'uintp', 'P', 8, 'long', 'l', 'L', 'longlong', 'q', 9, 'ulonglong', 'Q', 10, 'half', 'e', 23, 'f', 11, 'double', 'd', 12, 'longdouble', 'g', 13, 'cfloat', 'F', 14, 'cdouble', 'D', 15, 'clongdouble', 'G', 16, 'O', 17, 'S', 18, 'unicode', 'U', 19, 'void', 'V', 20, 'M', 21, 'm', 22, 'bool8', 'Bool', 'b1', 'float16', 'Float16', 'f2', 'float32', 'Float32', 'f4', 'float64', 'Float64', 'f8', 'float128', 'Float128', 'f16', 'complex64', 'Complex32', 'c8', 'complex128', 'Complex64', 'c16', 'complex256', 'Complex128', 'c32', 'object0', 'Object0', 'bytes0', 'Bytes0', 'str0', 'Str0', 'void0', 'Void0', 'datetime64', 'Datetime64', 'M8', 'timedelta64', 'Timedelta64', 'm8', 'int64', 'Int64', 'i8', 'uint64', 'UInt64', 'u8', 'int32', 'Int32', 'i4', 'uint32', 'UInt32', 'u4', 'int16', 'Int16', 'i2', 'uint16', 'UInt16', 'u2', 'int8', 'Int8', 'i1', 'uint8', 'UInt8', 'u1', 'complex_', 'int0', 'uint0', 'single', 'csingle', 'singlecomplex', 'float_', 'intc', 'uintc', 'int_', 'longfloat', 'clongfloat', 'longcomplex', 'bool_', 'unicode_', 'object_', 'bytes_', 'str_', 'string_', 'int', 'float', 'complex', 'bool', 'object', 'str', 'bytes', 'a'])

1.6    定义自己的数据类型

t=np.dtype('f8')     # 'f‘表示浮点型,8表示占的字节数,所以这是一个float64的类型。我们给它定 
                     #  义了一个自己的名字就是’t'

a=np.arange(7, dtype=t)
a.dtype

out:

dtype('float64')

dtype类的属性

上面我们定义了一个数据类型’t‘,它相当于一个类dtype的实例,我们可以通过它来查看一下类dtype的属性有哪些。

不难看出:char显示了该数据类型t的字符编码‘d',也就是t是双精度浮点数;type显示了t的类型,str含义如下:

1.7    创建自定义数据类型

类似C语言里面的结构体,定义了一个复合的数据类型。

例如:自定义一个表示商品信息的数据类型:这个类型包含三个部分:一,用一个长度为40个字符的字符串来记录商品名称,用一个32位的整数来记录商品的库存数量,最后用一个32位的单精度浮点数来记录商品价格。

(1)创建数据类型:

t = np.dtype([('name',np.str_, 40), ('numitems', np.int32), ('price', np.float32)])
t
out:
dtype([('name', '<U40'), ('numitems', '<i4'), ('price', '<f4')])

(2)   查看某一字段数据类型

t['name']

out:

dtype('<U40')

(3)   利用自定义的数据类型创建数组

itemz = np.array([('Meaning of live DVD', 42, 3.14), ('Butter', 13, 2.72)], dtype=t)
itemz[1]

out:
('Butter', 13, 2.72)

1.8    一维数组的索引和切片&利用步长-1来翻转数组

a = np.arange(9)
print(a)
print(a[3:7])
print(a[:7:2])  # 步长为2
print(a[::-1])  # 利用步长-1翻转数组

out:

[0 1 2 3 4 5 6 7 8]
[3 4 5 6]
[0 2 4 6]
[8 7 6 5 4 3 2 1 0]

1.9   多维数组的切片和索引

reshape创建多维数组

b = np.arange(24).reshape(2,3,4) # 请注意它的排列方式,这是一个两层的3x4的三维矩阵
print(b.shape)
print(b)

out:

(2, 3, 4)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

数组元素索引的表示方式a[1,2] or/and a[1][2] 以及列表元素索引

以前我们总是用a[0][1]这样的方式来表示矩阵a的第一行的第2个元素。但是,再这里我们发现,numpy的矩阵可以直接用a[0,1]这样的方式表示。

a=np.arange(10).reshape(2, 5)
print(a)
print(a[0,1])     
print(a[0][1])
#测试三维矩阵b
b[1,0,0]

out:

[[0 1 2 3 4]
 [5 6 7 8 9]]
1
1
12

但是,经过测试Python自带的列表(list)不能使用这样a[0,1]的方式,还是只能使用a[0][1]这样的方式。

用省略号'...'来表示遍历剩下的维度

b[0]等价于b[0, : , : ]等价于 b[0, ...]

结果都是:

 array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

使用-1进行多维数组的翻转

b[::-1]   # 两个矩阵前后翻转

out:

array([[[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]],

       [[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]]])

b[:,::-1,:]   # 翻转每矩阵的行

out:
array([[[ 8,  9, 10, 11],
        [ 4,  5,  6,  7],
        [ 0,  1,  2,  3]],

       [[20, 21, 22, 23],
        [16, 17, 18, 19],
        [12, 13, 14, 15]]])

1.10    改变数组的维度

使用reshape将数组展平

将数组展平b.ravel()、b.flatten():维度变为(长度,)

用元组设置维度:b.shape=(6,4) 等价于 b=b.reshape(6,4)

矩阵转置 b.transpose() 或者 b.T

b.resize((2,12))功能和reshape(2,12)一样,不同点是,resize会直接改变b的值

还有一点需注意:resize((a,b))是必须要指明a,b的值的,例如如果要把矩阵展开为一个行向量,reshape(1,-1)它是自动计算个数并展开的,但是resize必须指明a=1,b=24,否则报错。

1.11    数组的组合(合并)

首先创建两个数组a和b:

水平组合:np.hstack((a,b))或者np.concatenate((a,b), axis=1)

horizontal:水平的,横向的

stack:堆放

concatenate:串联

axis:坐标轴 

垂直组合:np.vstack((a,b))或者 np.concatenate((a,b), axis=0)

vertical:垂直的

深度组合 :np.dstack((a,b))

两个矩阵对应的每一对元素组成一个1x2的矩阵

列组合:column_stack

将每一列的元素组合到一块

行组合 row_stack

1.12    数组分割

水平分割 np.split(a,3)分成3份

注意它的意思:水平分割就是拿个刀从左到右沿着水平方向依次切三刀,把数组分成三份 

split:分裂,均分

另一种方法:

垂直分割:np.vsplit(a,3)

 

深度分割 np.dsplit(a, 3)

1.13    数组的属性

维数:b.ndim

元素个数:b.size

数组每个元素在内存中所占字节数:b.itemsize

数组每个元素的数据类型:b.dtype

数组所有元素所占存储空间:b.nbytes 其实就是size*itemsize 

转置:b.T或者b.transpose()

注意:一维数组的转置是它本身,这也是为什么我们要把一维数组reshape为二维数组的原因。

复数实部:b.real

复数虚部:b.imag

如果数组中包含复数元素,则其数据类型自动变为复数型

 

flat属性 :允许我们像遍历一维数组一样去遍历多维数组

 

获取数组元素

flat是一个可以赋值的属性, 对flat属性赋值将导致整个数组的元素都被覆盖

也可以给指定元素赋值

1.14    数组的转换:将数组转换为Python列表

转变数组元素的数据类型: b.astype(int)

猜你喜欢

转载自blog.csdn.net/wdx1993/article/details/83753504