一、Numpy库与多维数组

# Author:Zhang Yuan

import numpy as np

#NumPy 最重要的一个特点是其 N 维数组对象 ndarray。

#ndarray对象的维度是通过多层[]来确定的。[...]表示一维数据,[[...]]表示二维数据,[[[...]]]表示三维数据...

# [,]中的逗号,表示当前所在维度层的数据划分。[1,2,3] 一维划分。[[1, 2], [3, 4]] 外部逗号为第一层维度(行)划分,内部逗号为第二层维度(列)的划分

# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替

#赋值系列---------------------------------------------------------------
#原数据输入的方式形成数组:
#原数据输入可以是各种类型。
#"层次相同、数据个数相同"会默认转成多维数组,也就是严格符合多维数组格式的会自动转换.
print(np.array([1,2,[3]]))  #[1 2 list([3])],只有一个二层次
print(np.asarray([(1,),2,[3]]))  #[(1,) 2 list([3])],只有一个一层次
print(np.array([(1,),(2,),[3,]]))  #[[1],[2],[3]],都是二层次,转换
print(np.asarray([(1,),(2,),(3,)]))  #[[1],[2],[3]],都是二层次,转换
print(np.array([(1,2),(3,)]))  #[(1, 2) (3,)],都二层,但大小不同
print(np.asarray([(1,2),(3,4)]))  #[[1, 2],[3, 4]],都二层且大小相同,转换

#创建的方式形成数组:
#以shape维度描述来创建。
print(np.zeros((3,2))) #empty(),ones()
#以buffer来创建,用于实现动态数组。
#buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
print(np.frombuffer(b'Hello World',dtype =  'S1'))
print(np.frombuffer(np.array([1,2,3,4,5]),dtype=int))
#以迭代对象来创建
print(np.fromiter(range(5),dtype=int))
#以数值范围来创建
print(np.arange(10,20,2)) #[10  12  14  16  18]
print(np.linspace(1,10,10)) #[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
print(np.logspace(1,2,num=2)) #[ 10. 100.]
#--------------------------------------------------------------------------

#访问系列------------------------------------------------------------------
#切片还可以包括省略号 ...,来使选择元组的长度与数组的维度相同。如果在行位使用省略号,它将返回包含行中元素的 ndarray
#多维数组的切片和索引[,]中第一层逗号表示维度划分,第一层逗号分割的左右部分一定是按照维度顺序.
#多维数组若没有第一层逗号,会默认加上第一层逗号。但仅传入元组括号省略。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[...,1:]) # [[2 3],[5 6],[8 9]],相当于a[:,1:].
print(a[(1,2)])  # 6, 仅传入元组括号省略:a[1,2]=6.
print(a[[1,2]])  # [[4 5 6],[7 8 9]], 默认加上第一层逗号,相当于a[[1,2],]
print(a[[-1,-3]]) #[[7 8 9],[1 2 3]], 默认加上第一层逗号,相当于a[[-1,-3],]
print(a[(1,2),]) # [[4 5 6],[7 8 9]],相当于a[(1,2),:],行1、2,列全部

#多维多值索引一定要一一配对,且输出形式与输入的索引形式相同
print(a[[0,1,2], [0,1,0]])  #[1 5 7],多值索引。一对一:0-0,1-1,2-0
print(a[ [ [0,0],[2,2] ] , [ [0,2],[0,2] ] ]) #[[1 3], [7 9]]
print(a[np.array([[1],[2]]),np.array([[0],[2]])]) #[[4], [9]]
print(a[ [[1],[2]] , [[0],[2]] ]) #[[4], [9]]

#多维多值索引各维度层次不同,会自动默认到最高层次.
#各维度表示形式相同,点对点匹配,且大小必须相同。各维度表示形式不同,以不同的形式分别匹配。
x=np.arange(12).reshape((3,4))
'''x=array([[0, 1, 2,  3],
            [4, 5, 6,  7],
            [8, 9, 10, 11]])'''
print(x[ [1,2,0] , [[[3,1,0]]] ]) #[[[7 9 0]]] 各维度表示形式相同,点对点匹配;层次不同,会自动默认到最高层次.
x1=x[ [[1],[2],[0]] , [[3,1,0]] ] #[x]配 [a,b,c,d]表示:按a,b,c,d顺序索引第x行
'''x1=array([[ 7,  5,  4],
             [11,  9,  8],
             [ 3,  1,  0]]) '''

x2=x[ [[1,2,0]] , [[3],[1],[0]] ] #[a,b,c,d]配[x]表示:按a,b,c,d顺序索引第x列
'''x2=array([[ 7, 11,  3],
             [ 5,  9,  1],
             [ 4,  8,  0]])'''
#其中x1、x2互为转置矩阵

#第一维行为变独立( array([[1],[3]]), array([[2, 5]]) )
np.ix_([1,3],[2,5])
print(x[np.ix_([1,2,0],[3,1,0])])
'''[ [ 7  5  4]
     [11  9  8]
     [ 3  1  0] ]'''

#以布尔数组np.array([True,False,...])形式可以过滤
x= np.array([1,2,3,4,5,6])
x[np.array([True,False,True,False,True,False])] #array([1, 3, 5])
x[x > 2] #array([3, 4, 5, 6])
a = np.array([np.nan,  1,2,np.nan,3,4,5])
print(a[~np.isnan(a)]) #[1. 2. 3. 4. 5.],其中 ~ 取补运算符,按位取反.
#----------------------------------------------------------------------

#当运算中的 2 个数组的形状不同时,但要具备拉升可匹配性Broadcasting,numpy 会把数组自动拉升Broadcasting到相同,在进行元素运算

#对于一个多维数组a,如果a已经分配内存了,其转置a.T与a共享内存,且存储顺序也是一样的。
# 如果希望a.T与a存储顺序不同,可以需要重新分配内存:a.T.copy()。
# 或者控制遍历顺序:
# for x in np.nditer(a, order='F'):Fortran order,即是列序优先;
# for x in np.nditer(a.T, order='C'):C order,即是行序优先;

# Numpy数组操作------------------------------------------------------
# 修改数组形状:
#     reshape    不改变数据的条件下修改形状
#     flat    数组元素迭代器
#     flatten    返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
#     ravel    返回展开数组
# 翻转数组:
#     transpose    对换数组的维度
#     ndarray.T    和 self.transpose() 相同
#     rollaxis    向后滚动指定的轴
#     swapaxes    对换数组的两个轴
# 修改数组维度:
#     broadcast    产生模仿广播的对象
#     broadcast_to    将数组广播到新形状
#     expand_dims    扩展数组的形状
#     squeeze    从数组的形状中删除一维条目

#使用细节:
#flat数组元素迭代器
a = np.arange(9).reshape(3,3)
for row in a:print(row) #打印行
for element in a.flat:print (element) #打印元素

#可以先定义格式,再赋值
c=np.empty((4,3))
c.flat=[i for i in range(12)]

#运算也遵循相同结构点对点,不同结构分配匹配原则
x = np.array([[7], [8], [9]])
x1= np.array([7, 8, 9])
y = np.array([4, 5, 6])
print(x+y)  #结果不同,分别运算。
print(x1+y) #结构相同,一对一运算。
print(x*y)  #结果不同,分别运算。
print(x1*y) #结构相同,一对一运算。



#---------------------------------------------------------------

猜你喜欢

转载自www.cnblogs.com/i201102053/p/10878454.html