Numpy 笔记

Numpy基础

Numpy基本使用

  1. Numpy可用来创建N维数组,N-dimension array。简单的创建一个ndarray,创建出的对象的类型为numpy.ndarray
numpy.array([1,2,3,4,5])
> array([1,2,3,4,5])
type(numpy.array([1,2,3,4])
> numpy.ndarray
  1. ndarray即多维数组中的元素类型都是一致的,这与list列表不同
  2. 查看以及修改ndarray中的元素类型。使用dtype属性以及astype()方法
data.dtype  # dtype获取数组中的元素的类型
> dtype('int32')
new_data=data.astype(np.float)  # 数组中的元素的类型必须一样,不同于list,有时我们需要修改一个数组中的元素的类型,使用astype()来修改

a=np.array([1,2,3])
b=np.array([1.,2.,3.,4.])  # 1. 1.0两个其实是一样的,前者简写了而已
c=np.array([1.0,2.0,3.0,4.0])

a.dtype,b.dtype,c.dtype
> (dtype('int32'), dtype('float64'), dtype('float64'))
  1. 查看一个ndarray的形状,使用shape属性,得到的是一个元组
data.shape
> (3,)

# (3,)是一维的维度,表示横向的3个元素
# (1,8)是二维的维度,表示1行8列
  1. 获取ndarray的个数使用属性size,获取ndarray的维度使用属性ndim
  2. 创建一个ndarray,对传入的参数进行相应的设置来初始化生成的ndarray
numpy.array([1,2,3,4])

numpy.array([1,2,3,4],dtype=np.float)  # dtype参数控制ndarray中的数据类型

dc = numpy.array([1,2,3,4,5,6,7,8],ndim=2)  # ndim参数控制这个ndarray的维度

dc.shape
> (1,8)

numpy.array([[1,2,3,4],[2,3,4,5],[3,4,5,6]])  # 传入一个嵌套列表,就得到一个多维数组
  1. 创建全0数组
# numpy有专门的函数创建具有某些特征的ndarray
numpy.zeros((3,10)) # 参数是一个shape描述该ndarray的形状传入一个元组
> array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
da=numpy.array([[1,2,3,4],[2,3,4,5],[3,4,5,6]])

# ...like这个方法创建数组,其参数就是一个数组,其会根据传入数组的shape来创建同shape的全0数组
numpy.zeros_like(da) # 创建一个3行4列的全0数组
  1. 还有全1和全空数组,用法同上。分别是numpy.ones()numpy.empty(),他们同样有…like函数
  2. 创建对角线数组
# 创建对角线ndarray即主对角线为1的单位矩阵
np.eye(4,dtype=int)
> array([[1, 0, 0, 0],
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, 0, 0, 1]])

np.eye(4,dtype=int,k=1) # 只能创建2维数组,且是正方形的,k代表偏移
> array([[0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, 0, 0, 1],
         [0, 0, 0, 0]])

np.eye(4,dtype=int,k=-1)
> array([[0, 0, 0, 0],
         [1, 0, 0, 0],
         [0, 1, 0, 0],
         [0, 0, 1, 0]])
         
np.identity(4)  # 此方法只能创建无偏移的单位矩阵
> array([[1., 0., 0., 0.],
         [0., 1., 0., 0.],
         [0., 0., 1., 0.],
         [0., 0., 0., 1.]])
         
np.diag([1,2,3,4,5])  # 该方法功能更多,能指定对角线元素,自己确定方阵大小
> array([[1, 0, 0, 0, 0],
         [0, 2, 0, 0, 0],
         [0, 0, 3, 0, 0],
         [0, 0, 0, 4, 0],
         [0, 0, 0, 0, 5]])
         
np.diag([1,2,3,4,5,],k=2) # 还可以偏移
> array([[0, 0, 1, 0, 0, 0, 0],
         [0, 0, 0, 2, 0, 0, 0],
         [0, 0, 0, 0, 3, 0, 0],
         [0, 0, 0, 0, 0, 4, 0],
         [0, 0, 0, 0, 0, 0, 5],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0]])
         
de=np.arange(16).reshape((4,4))
> array([[ 0,  1,  2,  3],
         [ 4,  5,  6,  7],
         [ 8,  9, 10, 11],
         [12, 13, 14, 15]])
np.diag(de)  # 可以获取de这个数组中对角线的数组
> array([ 0,  5, 10, 15])
np.diag(de,k=-1)  # 获取偏移-1对象线值的数组
> array([ 4,  9, 14])
  1. 创建等差、等比数组
# 等差
np.arange(1,100,3)  # 根据步长创建,且是左闭右开;参数意义创建1到99的步长为3的数组
> array([ 1,  4,  7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
         52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97])
# 等比
np.linspace(1,10,5)  # 根据数量创建,左闭右闭;参数意义创建1到10的5个等比例的数组
> array([ 1.  ,  3.25,  5.5 ,  7.75, 10.  ])
  1. 自定义类型的数组,需要先创建一个数组类型,然后创建一个新数组时传入dtype参数你的自定义数组类型来生成一个自定义的数组
# np.dtype({'names':[],'formats':[]})自定义数组类型的写法,names的value指每一个元素中的名称,formats指每一个元素的数据类型
my_type=np.dtype({'names':['book','version'],'formats':['S40',np.int]})  # 自定义一个ndarray的类型为my_type
my_books=np.array([('learn java',1),('learn python',3),('learn C++',2)],dtype=my_type)
my_books.dtype
> dtype([('book', 'S40'), ('version', ')])

my_books[1] # 根据索引获取一个元素
> (b'learn python', 3)

my_books['book']  # 根据类型中的name获取所有该name的元素组成的数组
> array([b'learn java', b'learn python', b'learn C++'], dtype='|S40')

my_books[1]['book']  # 混合索引与name,先获取一个索引对应的元素,后获取其name
> b'learn python'

my_books['book'][1]  # 先获取所有book name组成的数组,再按索引
> b'learn python'

my_books['book'][1]='this is changed'  # 可通过索引修改指定元素,但不能新增
  1. 还可以从一个函数创建数组
def foo(x):
    return x*2
np.fromfunction(foo,(5,))  # 该方法根据方法创建ndarray,第二个参数表示维度,方法的参数个数与ndarray的维度对应
> array([0., 2., 4., 6., 8.])

np.fromfunction(lambda i,j:(i+1)*(j+1),(5,5),dtype=np.int)  # 可以使用lambda简化一个函数
> array([[ 1,  2,  3,  4,  5],
       [ 2,  4,  6,  8, 10],
       [ 3,  6,  9, 12, 15],
       [ 4,  8, 12, 16, 20],
       [ 5, 10, 15, 20, 25]])

Numpy索引和切片

  • 普通的用法其索引跟列表一样,不过是变成了多维的

利用下标也就是索引获取数组的元素

下标是整数
  • 多维数组有种简单的用法,可以将多维的下标写到一个下标内,依次代表个维度的索引
a[1][1][1]
> 17
a[1,1,1]
> 17
a[(1,1,1)]
> 17
# 上述索引操作相互等价
  • 同列表一样可以通过索引对数组进行修改
下标是列表
  • 当下标是列表时会创建一个新的数组
  • 组合多个元素
c[[0,1]] == c[0],c[1]  # 下标是列表相当于组合其他元素

c[[0,2],[1,2]] == c[0,1],c[2,2] # 下标是多个list,每个list是从其对应的维度上取该维度的数组最后再组合

c=np.logspace(1,3,12).reshape(3,4)
c
> array([[  10.        ,   15.19911083,   23.101297  ,   35.11191734],
        [  53.36699231,   81.11308308,  123.28467394,  187.38174229],
        [ 284.80358684,  432.87612811,  657.93322466, 1000.        ]])
c[[0,2],[1,2]]  # 这个组合其实就是组合下面的,在0轴上的0,2元素中再分别取1,2元素
> array([ 15.19911083, 657.93322466])
c[0,1],c[2,2]
> (15.199110829529339, 657.9332246575682)

# 重复list索引取到多次同一值
c[[2,2,2]]
> array([[ 284.80358684,  432.87612811,  657.93322466, 1000.        ],
         [ 284.80358684,  432.87612811,  657.93322466, 1000.        ],
         [ 284.80358684,  432.87612811,  657.93322466, 1000.        ]])
下标是数组
  • 其下标获取数据的方式跟下标是列表的用法相同,不过是将list换成了数组,list的值变为了数组中的值
b=np.linspace(0,100,5)
b
> array([  0.,  25.,  50.,  75., 100.])

b[np.array([2,3,2,3,2,3])] # == b[[2,3,2,3,2,3]]
> array([50., 75., 50., 75., 50., 75.])
  • 传入的数组可以是一个bool类型的数组,并根据bool值决定对应元素是否组成新数组
b==50  # 数组判断,判断里面每个元素,得到一个bool的元组
> array([False, False,  True, False, False])
t=b==50
t
> array([False, False,  True, False, False])
b[t]  # 根据bool数组来判断并取到相应元素
> array([50.])

b[b>50]  # 这样写更简洁
> array([ 75., 100.])
  • ndarray可以通过执行一个判断操作来判断每个元素是否满足条件,生成一个bool数组;其相当于一个for循环对所有元素执行这个判断操作
b==50
> array([False, False,  True, False, False])

b%2==0
> array([ True,  True,  True, False,  True])

  • 多维数组的下标用法也遵循1对1的原则,各维度相互对应取
e[np.array([0,1]),np.array([3,4])]  # 多维ndarray的一对一取索引原则
# 等同于 e[[0,1],[3,4]]==e[0,3],e[1,4]

切片

  • ndarray的切片与list相似都是左闭右开的区间
  • 切片后的ndarray与原ndarray共用同一个视图,两者共享同一个内存空间,一个修改另一个同样也会修改
a=np.arange(10,20)
a
> array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
b=a[2:8]
b
> array([12, 13, 14, 15, 16, 17])
b[0]=1000  # 数组的切片与原数组共用内存空间,就是使用同一个视图
b
> array([1000,   13,   14,   15,   16,   17])
a  # 公用一个视图
> array([  10,   11, 1000,   13,   14,   15,   16,   17,   18,   19])
  • 对于一维数组的切片和list的切片一样,同样可以用步长、负步长等。
  • 对于二维或者多维的数组切片,也是在一维的基础上进行,不过是在每个轴方向上实施,最终获得重叠区域

b
> array([[ 0,  1,  2,  3,  4,  5],
         [10, 11, 12, 13, 14, 15],
         [20, 21, 22, 23, 24, 25],
         [30, 31, 32, 33, 34, 35],
         [40, 41, 42, 43, 44, 45],
         [50, 51, 52, 53, 54, 55]])
b[1:4]  # 多维数组切片
> array([[10, 11, 12, 13, 14, 15],
         [20, 21, 22, 23, 24, 25],
         [30, 31, 32, 33, 34, 35]])
b[1:4,2:5]  # 先切0轴,再切1轴
> array([[12, 13, 14],
         [22, 23, 24],
         [32, 33, 34]])
  • ndarray的切片中可以混合索引中的用法
b[:,[0,3]]  # 在0轴上切片取所有,在1轴上取0和3
> array([[ 0,  3],
         [10, 13],
         [20, 23],
         [30, 33],
         [40, 43],
         [50, 53]])

b[[1,4],1:5:3]
> array([[11, 14],
         [41, 44]])

ndarray的变形操作

ndarray变形

  • reshape()函数实现ndarray的shape的变换
a=np.arrange(10)
a.reshape((2,5))  # reshape中传入一个元组
> array([[0, 1, 2, 3, 4],
         [5, 6, 7, 8, 9]])
# 或者使用np.reshape()
np.reshape(a,(2,5))
> array([[0, 1, 2, 3, 4],
         [5, 6, 7, 8, 9]])
  • 传入reshape的元组的维度为-1,代表这个维度大小自适应
c=np.reshape(b,(-1,1))  # 这里-1是一个不存在的索引
# 其意义就是o轴自己判断元素数量
c
> array([[0],
         [1],
         [2],
         [3],
         [4],
         [5],
         [6],
         [7],
         [8],
         [9]])
  • 需要注意一些变换的不同
np.reshape(b,(10,))
> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.reshape(b,(1,10))
> array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
# 上面两个看似相同,实则不同,前者是变形为一个一维数组
# 后者变形为一个只有一行的二维数组
  • 还有一种改变ndarray的shape的方法,就是修改一个ndarray的shape属性的值
b.shape=(1,10)
b
> array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
# 这种方式与reshape()的区别在于reshape()会新生成一个ndarray
# 修改shape这种方式会直接改变原ndarray的shape而不是新生成一个

ndarray扁平化

  • 扁平化就是变化为一维数组
  • 实现扁平化有两个方法一个是ndarray实例的flatten()一个是ndarray实例的ravel()
# 扁平化一个数组,就是生成一个一维数组
# flatten生成新的数组,不共用一个视图
p=b.flatten()
p
> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 还可以使用ravel实现生成一维数组
# 该方法生成的数组与原数组共用视图
p=b.ravel()
p[0]=99
print(p)
print(b)
> [99  1  2  3  4  5  6  7  8  9]
  [[99  1  2  3  4]
   [ 5  6  7  8  9]]
  • 两者有不同

运算与通用函数

算数运算

  • numpy的优势就在于如果是一个list要对每一个元素进行计算,需要for循环每一个元素;numpy的话对一个数组进行运算,其中每一个元素都进行运算
  • 一个ndarray和一个标量进行运算,结果是返回一个新的数组
# 运算
lst=[1,20,28,37,18,56]
a=np.array(lst)
a*3
> array([  3,  60,  84, 111,  54, 168])
a-10
> array([[-10,  -9,  -8,  -7,  -6],
         [ -5,  -4,  -3,  -2,  -1]])
  • 对两个数组进行运算,需要确定两个数组的维度相同,或者可以进行广播
  • 广播:满足广播的两个数组,需要满足的条件是两个数组的任意一个轴的长度相同,可以是0轴与0轴,也可以是0轴和1轴。
# 广播
# 满足广播条件的计算要求,两个数组的任意一个轴需要长度相同
a
> array([[0, 1, 2, 3, 4],
         [5, 6, 7, 8, 9]])
m=np.arange(5)
m.shape,a.shape
> ((5,), (2, 5))
a+m
> array([[ 0,  2,  4,  6,  8],
         [ 5,  7,  9, 11, 13]])
n=np.arange(1,3).reshape((-1,1))
a.shape,n.shape
> ((2, 5), (2, 1))
a+n
> array([[ 1,  2,  3,  4,  5],
         [ 7,  8,  9, 10, 11]])

比较运算

np.array([6,4,3]) > np.array([9,5,1])  # 需要比较的数组大小相同
# 然后比较里面的每一个元素,最后得到的是一个bool类型的数组
> array([False, False,  True])
  • numpy的与或非是特定的
# Numpy中的与或非是
# logical_and,logical_or,logical_not,logical_xor
np.logical_or(np.array([True,False]),np.array([False,True]))
> array([ True,  True])
  • np.any只要参数中的数组有一个为True就是True,否则是False
  • np.all只有参数数组中全部为True才返回True,否则是False

通用函数

  • 查文档

你可能感兴趣的:(python相关)