Numpy_01

Posted collin-pxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Numpy_01相关的知识,希望对你有一定的参考价值。

# 引子:

# ndarray 是一个 numpy库提供的 同构数据多维模型
import numpy as np

list=[1,2,3,4,5,6]
myndarray=np.array(list)
# type(myndarray)  # numpy.ndarray
# myndarray.dtype  # dtype(‘int32‘)
# print(myndarray) # [1 2 3 4 5 6]
# print(myndarray.shape) # (7,1)
myndarray  
# array([1,
#       2, 
#       3, 
#       4, 
#       5, 
#       6])   #7行1列数据
array([1, 2, 3, 4, 5, 6])
# numpy的基本用法:

# 一,创建 ndarray:
# 1)np.array()方法: 接收一切序列类型对象,包括其他数组。
# 2)其他方法,如:np.zeros(),np.ones(),np.empty(),np.arange(),np.ones_like(),np.zeros_like(),
# np.eye(),np.empty_like(),np.identity()等。

# 1--ndarray的 基本属性:
import numpy as np
mylist=[1,2,3,4,5]
myarray=np.array(mylist)
print(myarray)            # [1 2 3 4 5]  矩阵

print(myarray.ndim)       # 1      维数
print(myarray.size)       # 5      元素总数
print(myarray.shape)      # (5,)   形状     一维数组的形状 (n,)或(1,n)
print(myarray.dtype)      # int32  数据类型
print(myarray.itemsize)   # 4      每个元素的字节大小  32位/8位(每字节)=4 字节

# 2--特殊的 ndarray:
# 2.1--np.zeros()函数:
np.zeros(5)       # array([0., 0., 0., 0., 0.])
np.zeros((2,3))

# 2.2--np.ones()函数:
np.ones(5)       # array([1., 1., 1., 1., 1.])
np.ones((2,3))    

# 2.3--np.empty()函数:
# empty函数可以创建一个没有具体值的数组(即垃圾值):
np.empty((2,2))     # 认为np.empty返回全0数组是不安全的,很多情况下,返回的都是一些未初始化的垃圾值,比如:
# array([[1.14800323e-311, 6.95177601e-310],
#        [6.95177601e-310, 1.14898595e-311]])

# 2.5--np.ones_like()函数和np.zeros_like()函数:
arr01=np.array([[1,2,3,4],[5,6,7,8]])
arro1
# array([[1, 2, 3, 4],
#       [5, 6, 7, 8]])

arr02=np.zeros_like(arr01)
arr02
# array([[0, 0, 0, 0],
#       [0, 0, 0, 0]])

arr03=np.ones_like(arr01)
arr03
# array([[1, 1, 1, 1],
#       [1, 1, 1, 1]])

arr04=np.array([["a",1,"s"],["c",2,"v"]])
arr04
# array([[‘a‘, ‘1‘, ‘s‘],
#       [‘c‘, ‘2‘, ‘v‘]], dtype=‘<U1‘)

arr05=np.ones_like(arr04)
arr05
# array([[‘1‘, ‘1‘, ‘1‘],
#        [‘1‘, ‘1‘, ‘1‘]], dtype=‘<U1‘)

# 2.6--np.arange()函数:模仿指定的ndarray创建全1或全0数组。
# arange函数类似于python的内置函数range,但arange函数主要用于创建数组。
np.arange(5)      # array([0, 1, 2, 3, 4])
np.arange(1,5)    # array([ 1, 2, 3, 4])
np.arange(1,10,2) # array([1, 3, 5, 7, 9])

# 2.7--np.eye()函数,np.empty_like()函数,np.identity()函数, np.asarray()函数:
# 用到再来学习。
# 二,ndarray 的数据类型

# Numpy既可以为新建的数组【推断】出合适的数据类型,也可以通过【dtype属性来指定类型】。
# Numpy有很多数据类型,记住下面这些常用的就可以:
# folat   int   complex复数    bool布尔     string_     python对象:object
# 各数据类型及代码以及数据类型的解释见《利用python及逆行数据分析(2)》p121

# 1--数据类型推断:
arr01=np.array([0,1,2,3,4])
arr01.dtype  # dtype(‘int32‘)


# 2--为数组指定数据类型时:
arr01=np.array([0,1,2,3,4],dtype=‘float64‘)
arr01.dtype  # dtype(‘folat64‘)
arr02=np.arange(10,dtype=‘float‘)
arr02.dtype  # dtype(‘float64‘)


# 3--使用astype显示转换数据类型,不改变原数组,返回一个新数组:
# 语法:newarr=arr.astype([np.]数据类型)方法 或 newarr=arr.astype(arr2.dtype)方法  使用其他数组的dtype作为参数。

# 3-1)将数值型转为字符串:
arr01=np.array([0,1,2,3,4],dtype=‘float64‘)
arr02=arr01.astype(np.string_)
arr01.dtype    # dtype(‘float64‘)
arr02.dtype    # dtype(‘S32‘)

# 3-2)将浮点型数组转为整数,并不会四舍五入,而是直接截断
arr01=np.array([0,1,2.5,3.1,4.2],dtype=‘float64‘)
arr02=arr01.astype(np.int32)
arr02.dtype  #dtype(‘int32‘)
arr02 # array([0, 1, 2, 3, 4])

# 3-3)将字符串型的数字的数组转成数值类型:
arr01=np.array([‘0‘,‘1‘,‘2.5‘,‘3.1‘,‘4.2‘])
arr02=arr01.astype(np.float64)
arr02        # array([0. , 1. , 2.5, 3.1, 4.2])
arr02.dtype  # dtype(‘float64‘)

# 如果数组里有字符型字符串,使用astype转为数值就会报错:
arr01=np.array([‘a‘,‘1‘,‘e‘,‘3.1‘,‘4.2‘])
arr02=arr01.astype(np.float64) #ValueError: could not convert string to float: ‘a‘
arr02

# 3-4)使用其他数组的数据类型   newarr=arr.astype(arr2.dtype)方法 
arr01=np.array([0,1,2,3,4],dtype=‘float64‘)
arr02=np.array(["1","4","5"])
arr03=arr02.astype(arr01.dtype)
arr03.dtype
# 三,数组和标量之间的运算 (+ - * /  **)
# 数组之所以很重要,是因为它不需要编写循环就可以对数组内每一个数据元素进行运算,通常称之为矢量化。
# -- 不同大小的数组之间的运算叫做广播,这里不对广播机制做深入了解。
# -- 大小相等的数组之间的任何算术运算都会将运算应用到元素级:

# 1--数组准备
arr=np.array([[1.,2.,3.],[4.,5.,6.]])   # 或 arr=np.arange(1.0,7.0).reshape(2,3)
arr
# array([[1., 2., 3.],
#        [4., 5., 6.]])

# 2--数组与数组:
# 2-1)数组×数组
arr*arr
# array([[ 1.,  4.,  9.],
#        [16., 25., 36.]])

# 2-2)数组-数组
arr-arr
# array([[0., 0., 0.],
#        [0., 0., 0.]])

# 3--数组与标量:
1/arr
# array([[1.        , 0.5       , 0.33333333],
#        [0.25      , 0.2       , 0.16666667]])

arr**2
# array([[ 1.,  4.,  9.],
#        [16., 25., 36.]])

arr-0.5
# array([[0.5, 1.5, 2.5],
#        [3.5, 4.5, 5.5]])

# 4--数组与标量的混合运算
3*arr+2
# array([[ 5.,  8., 11.],
#        [14., 17., 20.]])

# 5--数组元素比较, 返回布尔值类型数组
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
arr>arr2
# array([[ True, False,  True],
#        [False,  True, False]])
# 四,基本索引和切片

# Numpy 数组的索引方法非常多。

# 1 一维数组的元素索引和数组切片:

# 1)一维数组元素的访问:
arr=np.arange(10)
arr[5]  # 5

# 2)一维数组的切片:
arr[5:8]
array([5, 6, 7])

# 3)一维数组切片赋值:
# 会影响原数组(数组的切片是原数组的视图,这和python的list切片是原list的浅复制不同)之所以会这样,是因为Numpy是为大数据考虑的,
# 如果不是在原数组上操作,而是复制来复制去,会非常占用内存。
arr[3:7]=0          # 或: arr_slice=arr[3:7]  arr_slice=0
arr                 # array([ 0,  1,  2, 0, 0, 0, 0,  7,  8,  9])
arr_slice2=arr[6:9]
arr_slice2[0]=9999  # 改变切片的第一个元素值
arr_slice2[1:]=8888
arr                 #  array([   0,    1,    2,   0,   0,   0, 9999, 8888, 8888,    9])

# 4)一维数组切片的显式复制(浅复制):
# 语法:arr[5:8].copy()  
arr=np.arange(10)
arr2=arr[5:8].copy()
arr2[:]=777
arr2  # array([777, 777, 777])
arr   # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  原数组没变


# 2 高维(二维)数组元素的索引和切片:  三维数组暂时不需要考虑
# 1) 创建一个二维数组  (3,3) 
arr2d=np.arange(1,10).reshape(3,3) 
arr2d
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

# 1-1)二维数组的元素索引:
arr2d[2]
array([7, 8, 9])
arr2d[2][1]  # 或
arr2d[2,1]   8

# 1-2)二维数组的切片:
arr2d[:2]     # 沿着0轴选取元素
# array([[1, 2, 3],
#        [4, 5, 6]])
arr2d[:2].shape  #
# (2,3) 二维数组

arr2d[:2,1:]    
# array([[2, 3],
#        [5, 6]])
arr2d[:2,1:].shape 
# (2,2)

arr2d[:,1]  
# array([2, 5, 8])
arr2d[:,1].shape  
# (3,)  一维数组

arr2d[:,:1]
array([[1],
       [4],
       [7]])
arr2d[:,:1].shape  
#(3, 1) 二维数组

#当然,对切片的赋值也会影响到原数组:
arr2d[:,:1]=9
arr2d
array([[9, 2, 3],
       [9, 5, 6],
       [9, 8, 9]])
# 五,布尔索引

# 示例:
# 数组1:一个用于存储数据的数组以及一个存储姓名的数组(含有重复项)。
# 数组2:使用np.random中的 randn函数生成一些正态分布的随机数据。
# 1)生成数组1 names :
names=np.array(["Bob","Joe","Will","Bob","Will","joe","joe"])
names  # array([‘Bob‘, ‘Joe‘, ‘Will‘, ‘Bob‘, ‘Will‘, ‘joe‘, ‘joe‘], dtype=‘<U4‘)
# 2) 生成 数组2 data:
data=np.random.randn(7,4)
data
array([[ 0.13914193, -0.96275352,  0.35075216,  0.25364798],
       [-1.10364635, -0.2635838 , -0.84638153,  0.67202326],
       [-0.83869909, -0.06954938,  0.80021281, -2.44477926],
       [-0.08734994, -0.08249876,  0.07469813,  0.27376429],
       [ 1.0876769 ,  1.45565495, -2.602985  , -0.89583722],
       [-0.24046131,  0.68823067, -0.34271733, -1.67964804],
       [ 0.12394175,  2.32313088,  0.23627141,  1.7670217 ]])

# 1--获取一个布尔数组,并使用布尔数组获取另一个数组的数组切片:

# 1)等号==的使用
# 假设names 中每一个名字都对应 data中的每行数据,现在我们要选出对应于‘Bob’的每一行数据。
bool_Bob = names == ‘Bob‘  # names == ‘Bob‘  返回一个布尔类型的数组, ==在数组中也是矢量化的。
bool_Bob
# array([ True, False, False,  True, False, False, False])
# np.array([ True, False, False,  True, False, False, False]).shape  # (7,)
# data.shape  # (7,4)

# 将这个布尔数组作为 data 数组的索引: #【布尔型数组的长度】必须和【被索引的轴】长度一致。
data[names == ‘Bob‘]      # 相当于:data[ True, False, False, True, False, False, False]  或 data[bool_Bob]
array([[ 0.13914193, -0.96275352,  0.35075216,  0.25364798], [-0.08734994, -0.08249876,  0.07469813,  0.27376429]])


# 还可以将布尔型数组与切片,整数(或整数序列)混合使用:
data[names==‘Bob‘,2:]  # 与切片混合使用,第3列及以后列
array([[ 0.20745417,  1.59998866],
       [-1.54179944,  0.26520684]])
data[names==‘Bob‘,3]  # 与整数混合使用,第4列
array([0.59981237, 2.19444112])

# 2)不等号!=的使用:
data[names!=‘Bob‘]
array([[-1.52854216,  0.25771145, -1.23529507,  0.18793414],
       [-0.16193399, -0.51354289,  1.90586211, -0.58838872],
       [ 0.47066932,  1.69033558, -0.47329781, -0.01530668],
       [ 1.23895961, -1.91537102, -1.50733678,  0.16473193],
       [-0.59033351,  0.36576441,  2.36265923, -1.1060814 ]])

# 3) ~和==的联用,效果同 !=:
data[~(names==‘Bob‘)]
array([[-1.52854216,  0.25771145, -1.23529507,  0.18793414],
       [-0.16193399, -0.51354289,  1.90586211, -0.58838872],
       [ 0.47066932,  1.69033558, -0.47329781, -0.01530668],
       [ 1.23895961, -1.91537102, -1.50733678,  0.16473193],
       [-0.59033351,  0.36576441,  2.36265923, -1.1060814 ]])
# 4)逻辑或 |的使用(别忘了使用()):  python中的 or 在数组里是无效的
mask=(names==‘Bob‘)|(names==‘Will‘)
mask
array([ True, False,  True,  True,  True, False, False])
data[mask]
array([[ 0.9965483 , -0.88256842, -0.12551621,  0.59981237],
       [-0.16193399, -0.51354289,  1.90586211, -0.58838872],
       [ 0.28340236, -0.93341777, -0.48931644,  2.19444112],
       [ 0.47066932,  1.69033558, -0.47329781, -0.01530668]])

# 5)逻辑与 & 的使用: python中的 and 在数组中是无效的
mask=(names==‘Bob‘)&(names==‘Will‘)  
# names中元素的值是确定的,不可能既是‘Bob’又是的‘Will‘,所以可以预想 mask 的元素全是False
mask
data[mask]  # 空数组
array([], shape=(0, 4), dtype=float64)


# 2--通过布尔型索引来选取数组中所有符合条件的元素数据,并改变这些元素的值:
data[data<0]
array([-0.96275352, -1.10364635, -0.2635838 , -0.84638153, -0.83869909,
       -0.06954938, -2.44477926, -0.08734994, -0.08249876, -2.602985  ,
       -0.89583722, -0.24046131, -0.34271733, -1.67964804])   # 它的 shape是(14,) 一维数组
data[data<0]=0  # 对切片进行赋值
data  # 从而改变原数组:
array([[0.13914193, 0.        , 0.35075216, 0.25364798],
       [0.        , 0.        , 0.        , 0.67202326],
       [0.        , 0.        , 0.80021281, 0.        ],
       [0.        , 0.        , 0.07469813, 0.27376429],
       [1.0876769 , 1.45565495, 0.        , 0.        ],
       [0.        , 0.68823067, 0.        , 0.        ],
       [0.12394175, 2.32313088, 0.23627141, 1.7670217 ]])

data[data==0]=0.1  
data
array([[0.13914193, 0.1       , 0.35075216, 0.25364798],
       [0.1       , 0.1       , 0.1       , 0.67202326],
       [0.1       , 0.1       , 0.80021281, 0.1       ],
       [0.1       , 0.1       , 0.07469813, 0.27376429],
       [1.0876769 , 1.45565495, 0.1       , 0.1       ],
       [0.1       , 0.68823067, 0.1       , 0.1       ],
       [0.12394175, 2.32313088, 0.23627141, 1.7670217 ]])

data[(data==0.1)|(data<0.2)]=0.25  # 别忘了加()
data
array([[0.25      , 0.25      , 0.35075216, 0.25364798],
       [0.25      , 0.25      , 0.25      , 0.67202326],
       [0.25      , 0.25      , 0.80021281, 0.25      ],
       [0.25      , 0.25      , 0.25      , 0.27376429],
       [1.0876769 , 1.45565495, 0.25      , 0.25      ],
       [0.25      , 0.68823067, 0.25      , 0.25      ],
       [0.25      , 2.32313088, 0.23627141, 1.7670217 ]])


# 3--通过布尔型索引来选取数组中所有符合条件的行或列数据,并改变这些行或列的值:
# 1)为整行赋值:
data[names==‘joe‘]=7
data
array([[0.25      , 0.25      , 0.35075216, 0.25364798],
       [0.25      , 0.25      , 0.25      , 0.67202326],
       [0.25      , 0.25      , 0.80021281, 0.25      ],
       [0.25      , 0.25      , 0.25      , 0.27376429],
       [1.0876769 , 1.45565495, 0.25      , 0.25      ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ]])
# 2)为整列赋值:
bool_arr=np.array([False,False,True,False])
data=data.swapaxes(0,1)  # 先把 data 数组轴对换返回的是一个新的数组赋值给 data。
data[bool_arr]=100       # 为新数组data的行赋值,相当于为旧数组的列赋值。
data=data.swapaxes(0,1)  # 将 data再次转回来。
data
array([[  0.25      ,   0.25      , 100.        ,   0.25364798],
       [  0.25      ,   0.25      , 100.        ,   0.67202326],
       [  0.25      ,   0.25      , 100.        ,   0.25      ],
       [  0.25      ,   0.25      , 100.        ,   0.27376429],
       [  1.0876769 ,   1.45565495, 100.        ,   0.25      ],
       [  7.        ,   7.        , 100.        ,   7.        ],
       [  7.        ,   7.        , 100.        ,   7.        ]])
# 六,花式索引(整数数组索引)

# 与切片的一个很大不同点是,它总是将数据复制到新数组中,对花式索引结果的赋值,不影响原数组,因为其形状与原数组都不一样了,
# 自然没法赋值给原数组。

# 1) 首先准备一个8x4的数组:
arr84=np.empty((8,4))
for i in range(8):
    arr84[i]=i  # 为每一行赋一个值
arr84
array([[0., 0., 0., 0.],
       [1., 1., 1., 1.],
       [2., 2., 2., 2.],
       [3., 3., 3., 3.],
       [4., 4., 4., 4.],
       [5., 5., 5., 5.],
       [6., 6., 6., 6.],
       [7., 7., 7., 7.]])

# 2) 使用指定顺序的【整数列表】或【ndarray】作为索引来选取特定顺序的子集:
# 2-1)使用一个整数【列表】作为索引 (注意索引为列表,如果少了[]就会报错: IndexError: too many indices for array)

arr84[[4,3,0,6]]  # 取arr84数组的第5,第4,第1和第7行数据
array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])
arr84[[-3,-5,-7]]  #使用负的索引,会从数组的末尾开始选行,-3表示倒数第三行。
array([[5., 5., 5., 5.],
       [3., 3., 3., 3.],
       [1., 1., 1., 1.]])

# 2-2)使用多个整数列表作为索引:  返回一维数组  
# 分别从各个整数列表里各自选出对应元素组成位置元组 进行索引后组成一维数组
# 1)先准备一个数组:
newarr84=np.arange(32).reshape((8,4))
newarr84
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])
# 2)对于二维数组的花式索引最多可以使用两个整数列表:
# 对于二维数组,最多可用两个整数列表,列表的长度可不定,但两个列表的长度要保持一致,
# 第一个列表的【每个整数值】不能超过 0轴(行,第1维)的长度,第二个列表的【每个整数值】不能超过 1轴(列,第二维)的长度。
newarr84[[1,5,7,2],[0,3,1,2]]   # array([4,23,29,10])
newarr84[[1,5,7,2,5],[0,3,1,2,1]]  # array([4,23,29,10,21])

# 3)如果你想得到的不是一维数组,而是一个包含上述元素且按照上述元素出现顺序的矩形区域,那么可以使用下面两种方法:
# 此矩形区域的行数和列数都可以和原数组不同。
# 3-1):
newarr84[[1,5,7,2]][:,[0,3,1,2]]            # 4x4  分开写:new=newarr84[[1,5,7,2]],new2=new[:,[0,3,1,2]]   输出new2
# 另一种写法:newarr84[np.ix_([1,5,7,2],[0,3,1,2])]
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

newarr84[[1,5,7,2,5]][:,[0,3,1,2,1]]      # 5x5 分开写:new=newarr84[[1,5,7,2,5]],new2=new[:,[0,3,1,2,1]]   输出new2
# 另一种写法:newarr84[np.ix_([1,5,7,2,5],[0,3,1,2,1])]
array([[ 4,  7,  5,  6,  5],
       [20, 23, 21, 22, 21],
       [28, 31, 29, 30, 29],
       [ 8, 11,  9, 10,  9],
       [20, 23, 21, 22, 21]])

# 对花式索引的结果赋值,不影响原来的数组。
newarr84[np.ix_([1,5,7,2],[0,3,1,2])]=0
newarr84[np.ix_([1,5,7,2],[0,3,1,2])]
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])
newarr84
array([[ 0,  1,  2,  3],
       [ 0,  0,  0,  0],
       [ 0,  0,  0,  0],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [ 0,  0,  0,  0],
       [24, 25, 26, 27],
       [ 0,  0,  0,  0]])
# 七,数组转置和轴对换
# 转置是重塑的一种特殊形式,返回的是原数组的视图(不会进行任何复制操作)
# arr和arr.T ,arr.transpose() 都是arr的不同形式,对arr.T ,arr.transpose(),array.swapaxes()的赋值操作都会影响arr
# 1)array.T 属性  2)array.transpose()方法  3)array.swapaxes()方法

# 对于二维数组:
arr35=np.arange(15).reshape((3,5))
arr35
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

# 1)array.T 属性:
arr35.T
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr35  # arr35还是arr35
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

arr35.T[1]=-1  # 对转置后的第二行进行赋值:
arr35.T
array([[ 0,  5, 10],
       [-1, -1, -1],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr35  
array([[ 0, -1,  2,  3,  4],
       [ 5, -1,  7,  8,  9],
       [10, -1, 12, 13, 14]])

# 来做个计算矩阵内积的示例:np.dot   即矩阵的点乘
arr35=np.arange(15).reshape((3,5))
arrdot=np.dot(arr35.T,arr35)
arrdot
array([[125, 140, 155, 170, 185],
       [140, 158, 176, 194, 212],
       [155, 176, 197, 218, 239],
       [170, 194, 218, 242, 266],
       [185, 212, 239, 266, 293]])


# 2) arr.transpose(轴号元组)
# 对于二维数组:
arr35=np.arange(15).reshape((3,5))
arr35.transpose((1,0))
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr35
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

arr35=np.arange(15).reshape((3,5))
arr35.transpose((1,0))[0]=-6
arr35
array([[-6,  1,  2,  3,  4],
       [-6,  6,  7,  8,  9],
       [-6, 11, 12, 13, 14]])


# 3)array.swapaxes(一对要对换的轴编号)方法, 参数是两个轴号,不是元组。 
arr35=np.arange(15).reshape((3,5))
arr35.swapaxes(0,1)  # 也可 arr35.swapaxes(1,0)
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr35
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

arr35.swapaxes(0,1)[0]=-2
arr35
array([[-2,  1,  2,  3,  4],
       [-2,  6,  7,  8,  9],
       [-2, 11, 12, 13, 14]])

arr35

# 八,通用函数 ufunc:快速的元素级的数组函数
# 可以看作是简单函数(接受一个或多个标量值,并产生一个或多个标量值)的矢量化包装器。
# 许多ufunc都是简单的元素级变体,如sqrt,exp:

# 一元 ufunc:
# abs,fabs--计算整数,浮点数,复数的绝对值,对于非复数值,可以使用更快的fabs
# sqrt------计算各元素的平方根,相当于arr**0.5
# square----计算各元素的平方,相当于arr**2
# exp-------计算各元素的以e为底的指数
# log,log10,log2,log1p--分别表示自然对数,底数为10的log,底数为2的log,log(1+x)
# sign--计算各元素的正负号:1(正数),0(零),-1(负数)
# ceil--计算各元素的ceiling值,即大于等于该值的最小整数。 (天花板值)
# floor--计算该值的floor值,即小于等于该值的最大整数。(地板值)
# rint--将各元素的值四舍五入到最接近的整数,保留dtype。
# modf--将数组的小数和整数部分以两个独立数组的形式返回。
# isnan--返回一个表示哪些值是 NAN (not a number)的布尔型数组
# isfinite--返回一个表示哪些元素是有尽的(非inf,非NAN)的布尔型数组
# isinf--返回一个表示哪些元素是无穷的的布尔型数组
# cos,cosh,sin,sinh,tan,tanh--普通型和双曲型三角函数
# arccos,aeccosh,arcsin,arcsinh,arctan,arctanh--反三角函数
# logicl-not--计算各元素not x的真值。相当于 -arr

# 二元ufunc:
# add--将两个数组中对应的元素相加
# subtract--将两个数组中对应的元素相减
# multiply--将两个数组中对应的元素相乘
# devide,floor_divide--除法或向下圆整除法(丢弃余数)
# power--对于第一个数组中的元素A,根据第二个数组中的相应的元素B,计算A**B
# maximum,fmax--元素级的最大值计算,fmax将忽略NAN
# minimum,fmin--元素级的最小值计算,fmin将忽略NAN
# mod--元素级的取模计算(除法的余数)余数。
# copysign--将第二个数组中的符号复制给第一个数组中的值
# greater、greater_equal、less、less_equal、equal、not equal--执行数组元素的比较运算,产生布尔型数组。相当于中辍运算符 >,>=,<,<=,==,!=
# logical_and、logical_or、logical_xor--执行元素级的真值逻辑运算。相当于中辍运算符 &、|、^


# 示例:

# 一元ufunc函数示例:
# 1)np.sqrt(arr)  计算每个元素的平方根
arr=np.arange(10)
np.sqrt(arr)
array([0.        , 1.        , 1.41421356, 1.73205081, 2.        ,
        2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])

# 2)np.exp(arr)  计算各元素的以e为底的指数
np.exp(arr)
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
        5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
        2.98095799e+03, 8.10308393e+03])

# 3) np.modf(arr)  将数组的小数和整数部分以两个独立数组的形式返回
# 会返回两个数组(返回两个数组的ufunc比较少),它是python内置函数divmod的矢量化版本。
arrfloat=np.random.randn(7)*5
np.modf(arrfloat)
(array([ 0.06999584,  0.51758053, -0.46226613, -0.26251269,  0.36295513,
            0.84655061, -0.43529079]),
array([ 4.,  1., -6., -3.,  5.,  1., -2.]))


# 二元ufunc函数示例:
arr1=np.random.randn(8)
arr2=np.random.randn(8)

# 1)np.add(arr1,arr2)  对应位置元素求和
arr1
array([-0.11423455,  0.34311356,  0.97609564,  0.43885802,  1.61820549,
        -1.21456404, -0.62405483, -1.37193806])
arr2
array([-0.01736506,  1.5373613 ,  1.3406096 , -0.20445385,  0.22836248,
         -1.95019508,  1.39529547,  0.39184623])

np.add(arr1,arr2)
array([-0.13159961,  1.88047485,  2.31670524,  0.23440417,  1.84656797,
        -3.16475912,  0.77124064, -0.98009183])

# 2)np.maximum(arr1,arr2)  对应位置元素取较大值
np.maximum(arr1,arr2)
array([-0.01736506,  1.5373613 ,  1.3406096 ,  0.43885802,  1.61820549,
        -1.21456404,  1.39529547,  0.39184623])
# 九,使用数组进行面向数组编程

# 9.1--假设我们想得到一组值(网格型)上计算sqrt(x^2+y^2)。np.meshingrid(arr1,arr2)函数接受两个一维数组,并产生两个二维矩阵
# 假设一维数组的长度为n,那么二维数组的shape为(n,n)
#(对应于两个数组中所有的(x,y)对):
points=np.arange(-5,5,0.01)       # 一维数组   
xs,ys=np.meshgrid(points,points)  # xs,ys均为二维数组, 
xs
    array([[-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
           [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
           [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
           ...,
           [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
           [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
           [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99]])
ys

    array([[-5.  , -5.  , -5.  , ..., -5.  , -5.  , -5.  ],
           [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
           [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
           ...,
           [ 4.97,  4.97,  4.97, ...,  4.97,  4.97,  4.97],
           [ 4.98,  4.98,  4.98, ...,  4.98,  4.98,  4.98],
           [ 4.99,  4.99,  4.99, ...,  4.99,  4.99,  4.99]])


# 现在对函数的求值运算就好办了,把这两个数组当作两个浮点数那样编写表达式即可:
z=np.sqrt(xs**2+ys**2)  # xs**2+ys**2是数组间的运算得到一个新数组  然后再sqrt
z

    array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,
            7.06400028],
           [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
            7.05692568],
           [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
            7.04985815],
           ...,
           [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,
            7.04279774],
           [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
            7.04985815],
           [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
            7.05692568]])

# 作图
import matplotlib.pyplot as plt
plt.imshow(z,cmap=plt.cm.gray);plt.colorbar()
plt.title("Image plot of $sqrt{x^2+y^2})$ for a grid of values")
Text(0.5, 1.0, ‘Image plot of $\sqrt{x^2+y^2})$ for a grid of values‘)

技术图片

# 9.2-- numpy.where() 将条件逻辑表述为数组运算 

# 9-2-1)numpy.where(conditionarr,xarr,yarr)函数
# 三个参数都为数组,即python中三元表达式: x if condition else y 的矢量化版本。不改变 conditionarr, xarr,yarr,返回一个新的数组。

# 示例:假设我们有一个布尔数组cond和两个值数组xarr,yarr:
xarr=np.array([1.1,1.2,1.3,1.4,1.5])
yarr=np.array([2.1,2.2,2.3,2.4,2.5])
condarr=np.array([True,False,True,True,False])
np.where(condarr,xarr,yarr)
# np.where(cond,xarr,yarr).tolist()  #转化为列表
array([1.1, 2.2, 1.3, 1.4, 2.5])

# 如果使用python的列表推导式,应该是这样做:
results=[(x if cond else y) for x,y,cond in zip(xarr,yarr,cond)]  # 得到一个列表
results
# 使用纯python,对于大数组效率特别慢,当xarr和yarr是多维数组时,无能为力。
[1.1, 2.2, 1.3, 1.4, 2.5]


# 9-2-2)当第一参数为数组判断表达式,其余参数不为数组时
# numpy.where(condition,标量1或数组1,标量2或数组2)函数   np.where()函数的第二个和第三个参数可以不必是数组,也可以是标量或标量与数组的组合
# 在数据分析工作中,where通常用于根据一个数组而生成另一个新数组。
# 示例2:假设有一个随机数据组成的矩阵,你希望将所有的正值替换为2,将所有的负值替换为-2,使用where会很简单
arrrandn=np.random.randn(4,4)
np.where(arrrandn>0,2,-2)  # 根据一个数组而生成另一个新数组。
array([[-2,  2,  2,  2],
       [-2,  2,  2,  2],
       [-2, -2,  2, -2],
       [-2,  2,  2, -2]])

np.where(arrrandn>0,2,arrrandn)  # 只将正数用2替换,其余不变。  # 根据一个数组而生成另一个新数组。
array([[-2.86684263,  2.        ,  2.        ,  2.        ],
      [-0.1251956 ,  2.        ,  2.        ,  2.        ],
      [-0.34407839, -0.07410133,  2.        , -0.41481679],
       [-0.73640143,  2.        ,  2.        , -0.82490141]])


# 9-2-3)np.where(condition)
#只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标。
#这里的坐标以数组为元素的tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。
a = np.array([1,3,5,7,9])
print(np.where(a>5))     # (array([3, 4], dtype=int64),)  这是个元组
print(a[np.where(a>5)])  # [7 9]                          得到的是列表



# 9-2-4)numpy.where的嵌套使用:
# 两个布尔类型的数组cond1和cond2,如果对应元素都是True,就是11,如果只有第一个数组的元素是True,就是10,
# 如果只有第二个数组的元素是True,就是01,如果两个数组的对应元素都是False元,就是00,用列表接收他们。
results=[]
arr1=np.array([True,False,False,False,True])
arr2=np.array([False,False,True,False,True])
n=arr1.size
for i in range(n):
    if arr1[i] and arr2[i]:
        results.append(‘11‘)
    elif arr1[i]:
        results.append(‘10‘)
    elif arr2[i]:
        results.append(‘01‘)
    else:
        results.append(‘00‘)
results
[‘10‘, ‘00‘, ‘01‘, ‘00‘, ‘11‘]


# 使用np.where进行嵌套就可以写得更简单:
np.where((arr1 & arr2),‘11‘,np.where(arr1,‘10‘,np.where(arr2,‘01‘,‘00‘))).tolist()
[‘10‘, ‘00‘, ‘01‘, ‘00‘, ‘11‘]



# 9.3,数学和统计方法  聚合函数和其他函数

# 聚合函数:
# sum       沿着轴向计算所有的累计和,0长度的数组,累计和就是0
# mean      数学平均,0长度的数组平均值是 NAN
# std       标准差,可以选择自由度调整(默认分母是 n)
# var       方差,可以选择自由度调整(默认分母是 n)
# min,max   最小值和最大值
# argmin,argmax  最小值和最大值的位置

# 其他统计方法:
# cumsum    所有元素的累积和,第一个加数为0
# cumprod   所有元素的累积,第一个乘数是1

# 9.3.1 一些聚合函数(也叫缩减函数),比如sum,mean,std(标准差),可以作为数组的实例方法被调用,也可以作为顶级numpy函数使用,
# 对整个数组或某个轴向的数据进行统计计算。
# 比如: arr.mean() 和 np.mean(arr) 效果相同。

# 1)示例 1  对整个数组使用聚合函数:

# 准备一个正态分布的随机数组:
arr=np.random.randn(5,4)
# sum,mean,std的使用:
print(arr.mean(),"--",np.mean(arr))
print(arr.sum(),"--",np.sum(arr))
print(arr.std(),"--",np.std(arr))

    0.16849962731538337 -- 0.16849962731538337
    3.3699925463076674 -- 3.3699925463076674
    0.9828447058023279 -- 0.9828447058023279
    

# 1)示例 2  对数组的某个轴数据使用聚合函数:
# sum,mean,std的使用: axis=1 可以简写为 1  1表示列轴向(列号递增的方向,其实就是行)
print(arr.mean(axis=1),"--",np.mean(arr,axis=1))  # 计算每一列的平均值
print(arr.sum(axis=1),"--",np.sum(arr,axis=1))    # 计算每一列的和
print(arr.std(axis=1),"--",np.std(arr,axis=1))    # 计算每一列的标准差

    [ 0.39721479 -0.53907257  0.80701694  0.02321185  0.15412712] -- [ 0.39721479 -0.53907257  0.80701694  0.02321185  0.15412712]
    [ 1.58885916 -2.15629028  3.22806777  0.09284742  0.61650847] -- [ 1.58885916 -2.15629028  3.22806777  0.09284742  0.61650847]
    [0.64008158 0.66171982 0.67832542 0.677676   1.44256105] -- [0.64008158 0.66171982 0.67832542 0.677676   1.44256105]
    

# sum,mean,std的使用:
print(arr.mean(1),"--",np.mean(arr,1))  # 计算每一列的平均值   
print(arr.sum(1),"--",np.sum(arr,1))    # 计算每一列的和
print(arr.std(1),"--",np.std(arr,1))    # 计算每一列的标准差

    [ 0.39721479 -0.53907257  0.80701694  0.02321185  0.15412712] -- [ 0.39721479 -0.53907257  0.80701694  0.02321185  0.15412712]
    [ 1.58885916 -2.15629028  3.22806777  0.09284742  0.61650847] -- [ 1.58885916 -2.15629028  3.22806777  0.09284742  0.61650847]
    [0.64008158 0.66171982 0.67832542 0.677676   1.44256105] -- [0.64008158 0.66171982 0.67832542 0.677676   1.44256105]
    

# sum,mean,std的使用:
print(arr.mean(0),"--",np.mean(arr,0))  # 计算每一行的平均值
print(arr.sum(0),"--",np.sum(arr,0))    # 计算每一行的和
print(arr.std(0),"--",np.std(arr,0))    # 计算每一行的标准差


    [ 0.43711985  0.66037716 -0.3156837  -0.1078148 ] -- [ 0.43711985  0.66037716 -0.3156837  -0.1078148 ]
    [ 2.18559927  3.30188578 -1.57841849 -0.53907401] -- [ 2.18559927  3.30188578 -1.57841849 -0.53907401]
    [0.83383241 0.87271032 1.22192838 0.53762685] -- [0.83383241 0.87271032 1.22192838 0.53762685]
    


# 9.3.2 其他统计函数(非聚合函数)
# cumsum 所有元素的累计和 第一个加数是0
# umprod 所有元素的累积 第一个乘数是1
# 这两个函数不会使数组聚合,而是会产生一个中间结果的数组,这个数组的长度与原数组的长度一致。

# 示例1--对整个数组使用cumsum,umprod:
arr1=np.array([0,1,2,3,4,5,6,7])
arr1.cumsum()
array([ 0,  1,  3,  6, 10, 15, 21, 28], dtype=int32)

arr1.cumprod()
array([0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

arr2=np.array([1,2,3,4,5,6,7])
arr2.cumprod()
array([   1,    2,    6,   24,  120,  720, 5040], dtype=int32)

# 示例2--对数组的某个轴数据使用cumsum,umprod:
arr3=np.arange(9).reshape((3,3))
arr3
array([[0, 1, 2],
        [3, 4, 5],
        [6, 7, 8]])

arr3.cumsum(1)  # 1表示列轴向(列号递增的方向,其实就是行)
array([[ 0,  1,  3],
       [ 3,  7, 12],
       [ 6, 13, 21]], dtype=int32)


arr3.cumprod(1)
array([[  0,   0,   0],
       [  3,  12,  60],
       [  6,  42, 336]], dtype=int32)



# 9.4,布尔值数组的方法  
# 同样,下面的函数既可以作为数组实例的方法被调用,也可以作为顶级numpy函数使用。
# sum(),any(),all()
# 这些函数也可以用于非布尔类型数组,所有非0元素,都会被认为是True.

# 9.4.1 sum()函数
arr=np.random.randn(100)
print((arr>0).sum())  # 49   统计数组中元素大于0的个数   布尔类型数组的True相当于1,False相当于0
print(np.sum(arr>0))  # 49

# 9.4.2 any()和all(), any检查数组中是否至少有一个True,all检查数组中是否全是True
bools=np.array([False,True,False,False])
print(bools.any())    # True
print(np.any(bools))  # True
print(bools.all())    # False
print(np.all(bools))  # False


# 9.5,数组排序
# 和python的内建列表类型相似,Numpy数组可以使用sort方法按位置排序:
# arr.sort() in place sort, 会改变原数组。
# np.sort(arr),np.sort(arr,1) 顶层的np.sort()方法返回的是数组的copy,不会改变原数组。
# 其他排序方法:间接排序(参照高级numpy),与排序相关的其他种类的数据操作,比如根据一个表的某一列排序,(pandas会讲)

# 9.5.1 arr.sort()对整个一维数组排序:
arr=np.random.randn(6)
arr
array([ 0.28791664, -0.33857089, -0.25479571,  0.8856711 , -2.80537025,
            3.58768604])

arr.sort()
arr
array([-2.80537025, -0.33857089, -0.25479571,  0.28791664,  0.8856711 ,
            3.58768604])


# 9.5.2 arr.sort()对于二维数组排序:
arr2=np.random.randn(5,3)
arr2
array([[ 1.18081678,  0.17371794,  2.37109646],
       [ 0.25508294, -1.28392   , -0.29739046],
       [ 0.65719139, -1.42167423,  0.06661373],
       [ 0.5586866 , -0.64003369,  2.32344008],
       [-0.47146893, -0.14909249, -0.42267235]])


arr2.sort()  # 当没有参数时,实际默认参数为 1
# arr2.sort(1) 
arr2
array([[ 0.17371794,  1.18081678,  2.37109646],
       [-1.28392   , -0.29739046,  0.25508294],
       [-1.42167423,  0.06661373,  0.65719139],
       [-0.64003369,  0.5586866 ,  2.32344008],
       [-0.47146893, -0.42267235, -0.14909249]])


arr2=np.random.randn(5,3)
arr2
array([[-0.79484895,  0.46884083,  1.53851912],
       [ 0.62346424,  0.51440027,  0.22166369],
       [ 0.03477362, -1.9244294 ,  0.03262501],
       [-1.25440832, -0.09754629, -0.81348808],
       [-1.11063465,  0.04493534, -1.2358787 ]])


arr2.sort(0) 
arr2
array([[-1.25440832, -1.9244294 , -1.2358787 ],
       [-1.11063465, -0.09754629, -0.81348808],
       [-0.79484895,  0.04493534,  0.03262501],
       [ 0.03477362,  0.46884083,  0.22166369],
       [ 0.62346424,  0.51440027,  1.53851912]])


# 9.5.3  np.sort(arr),np.sort(arr,axis=1) ,np.sort(arr,axis=0)
# 只拿一维数组来举例:
arr=np.random.randn(6)
arr
array([-0.00642429, -0.17085358, -0.09756021, -0.26958744, -0.29145018,
           -0.8358323 ])

np.sort(arr)  # 返回新的数组,不改变原数组
array([-0.8358323 , -0.29145018, -0.26958744, -0.17085358, -0.09756021,-0.00642429])
arr
array([-0.00642429, -0.17085358, -0.09756021, -0.26958744, -0.29145018,-0.8358323 ])



# 9.6,唯一值与其他集合逻辑   
# Numpy 包含一些针对一维 ndarray 的基础集合操作。
# 注,都是numpy的顶层方法,ndarray对象不存在这些方法。

# np.unique(arr)                 计算arr的唯一值,并排序
# np.intersect1d(arr1,arr2)      计算两个数组的交集,并排序
# np.union1d(arr1,arr2)          计算两个数组的并集,并排序
# np.ind1d(arr1,arr2)            计算arr1的元素,是否存在于arr2中
# np.setdifferent(arr1,arr2)     差集,在arr1中,但不在arr2中的元素
# np.setxor1d(arr1,arr2)         异或集,在arr1中或在arr2中,但不在二者的交集中

# 以下只针对 np.unique(arr)   np.in1d(arr1,arr2) 进行讲解:

# 9.6.1 np.unique(arr) 返回的是数组中唯一值排序(去重后排序)后形成的数组。
names=np.array([‘Bob‘,‘Joe‘,‘Will‘,‘Bob‘,‘Will‘,‘Joe‘,‘Joe‘])
np.unique(names)
# names.unique()  这种用法不存在
array([‘Bob‘, ‘Joe‘, ‘Will‘], dtype=‘<U4‘)

ints=np.array([3,3,3,2,2,1,1,4,4])
np.unique(ints)
array([1, 2, 3, 4])


# 用纯python 来实现上面的例子:
# 使用set()函数,将数组转化为set集合,自动去重,然后用sorted()函数对set集合排序,得到列表:
# 知识点:set(ndarray对象)得到去重后的set集合, sorted(set)得到排序后的列表。

names=np.array([‘Bob‘,‘Joe‘,‘Will‘,‘Bob‘,‘Will‘,‘Joe‘,‘Joe‘])
names_set=set(names)
sorted(names_set)
[‘Bob‘, ‘Joe‘, ‘Will‘]


ints=np.array([3,3,3,2,2,1,1,4,4])
ints_set=set(ints)
sorted(ints_set)
[1, 2, 3, 4]


#  9.6.2 np.in1d(arr1,arr2)
# 用来检查一个数组中的值是否在另外一个数组中也出现,并返回一个和第一个数组长度一致的布尔类型数组。
values01=np.array([5,6,7,9,0,0,3])
values02=np.array([5,8,7,5])
np.in1d(values01,values02)
array([ True, False,  True, False, False, False, False])

以上是关于Numpy_01的主要内容,如果未能解决你的问题,请参考以下文章

Numpy_01

python numpy片段

numpy day01

Numpy库01_多维矩阵数据结构

在对象列表上使用 numpy 选择时生成新对象

如何创建片段以重复变量编号中的代码行