第2章 NumPy入门(2.1-2.2)_Python数据科学手册学习笔记

第2章 NumPy入门(2.1-2.2)

根据<<数据科学手册>> Python Data Science Handbook一书整理.

本章将详细介绍NumPy(Numerical Python的简称)提供了高效存储和操作密集数据缓存的借口.在某些方面,NumPy数组和Python内置的列表类型非常相似.但是随着数组在维度上变大,NumPy数组提供了更加高效的存储和数据操作.NumPy数组几乎是整个Python数据科学工具生态系统的核心.因此不管你对数据科学的哪个方面感兴趣,花点时间学习如何有效使用NumPy都是非常值得的.

2.1 理解Python中的数据类型

2.1.5 创建几个数组

import numpy as np
创建一个长度为10的数组, 数组的值都是0
-是zeros, 不是zero
-此函数有啥作用?
np.zeros(10, dtype=int)     
创建一个3 * 5的浮点型数组, 数组的值都是1

3 * 5 表示3行*5列, 输入代码是圆括号本身是成对出现的, 如果手动添加或者剪切, 可能会导致错误

np.ones((3,5),dtype=int)
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
创建一个3 * 5的浮点型数组, 数组的值都是3.14
np.full((3,5), 3.14)
array([[3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14]])
zeros,ones,full都是np下的函数, 可以创建数组.
-第一个参数告诉数组是多长, 或者是 n*k的数组 
-第二个参数,数值类型或者数值
np.zeros(10,dtype=str)
array(['', '', '', '', '', '', '', '', '', ''], dtype='<U1')
np.ones((3,3),dtype=int)
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
np.full(9,520)
array([520, 520, 520, 520, 520, 520, 520, 520, 520])
创建一个线性序列, 从0开始,20结束,步长2
-和内置的range()函数类似
np.arange(0,20,2)
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
创建一个5个元素的数组,这5个数均匀分配到0-1中
-分位数吗?
np.linspace(0,1,5)
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
np.linspace(4,20,5)
array([ 4.,  8., 12., 16., 20.]
创建一个3*3,在0-1均匀分布的随机数组成的数组
-重点是0-1
-均匀分布是什么意思
np.random.random((3,3))
array([[0.39362852, 0.25206974, 0.88385296],
       [0.36547614, 0.34461809, 0.7989048 ],
       [0.7369659 , 0.21725593, 0.92850852]])
np.random.random((3*3))
array([0.28620252, 0.18814101, 0.51808316, 0.09341987, 0.78624051,
       0.89402738, 0.23804843, 0.04750264, 0.99956259])
np.random.random(5)
array([0.76369557, 0.88767111, 0.93486428, 0.54337144, 0.60357903])
创建一个3*3的,均值为0,标准差为1的
-正太分布数组
np.random.normal(0,1,(3,3))
array([[ 0.90030434, -1.50711765,  0.97764385],
       [-0.31173987, -0.84110574, -0.10047986],
       [-0.43478952,  1.50298937,  0.73763183]])
np.random.normal(1.5,0.4,100)   #生成均值为1.5,标准差为0.4的100个数字.怎么只显示2位小数
array([1.22261068, 1.58441532, 1.88802132, 0.61486983, 1.87470827,
       2.25946452, 1.03590926, 1.33094771, 1.4062705 , 1.11332783,
       1.40300437, 1.56448717, 1.84108864, 1.889423  , 0.77694291,
       0.68180117, 1.30913434, 1.86453287, 1.47528384, 1.57611792,
       1.18340949, 1.52063669, 1.59611354, 1.42870295, 1.74599812,
       0.87469452, 0.74602807, 1.12764331, 1.25820621, 1.7901757 ,
       1.63144372, 1.53547336, 1.69190459, 1.56495873, 1.92058924,
       1.32189662, 1.81971028, 1.46019658, 2.35699722, 1.96548058,
       2.65711447, 0.89155833, 1.90166715, 1.88020944, 1.49726831,
       1.55377297, 1.25409672, 0.94901106, 0.94586283, 1.67326062,
       1.37021414, 1.63778177, 1.61532023, 1.01930684, 1.73838839,
       2.39846604, 1.1897899 , 0.98619697, 1.41209562, 1.66616348,
       1.67276465, 1.6177355 , 1.17221527, 1.81797366, 1.71753876,
       1.59004372, 2.19224441, 1.54545624, 1.62140601, 2.05344465,
       1.64692645, 1.51883407, 1.83548018, 1.29491494, 1.71556491,
       1.04304926, 1.04311419, 2.25142503, 1.65532576, 1.25867277,
       0.98532785, 0.76105179, 0.7609183 , 1.84616896, 1.95658462,
       2.37700902, 1.62810267, 1.62762617, 1.66713729, 1.87285054,
       1.88304677, 1.32029194, 1.2275771 , 1.38059868, 0.73470536,
       2.19813629, 1.96004672, 1.98630112, 1.74666125, 1.18260392])
创建一个3*3的,0-10区间的随机数组成的数组
np.random.randint(0,10,(3,3))
array([4, 3, 4, 4, 8, 4])
np.random.randint(90,100,(2,2))
array([[94, 90],
       [92, 99]])
创建一个3*3的单位矩阵
np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
创建一个由3个整数组成的未初始化的数组
-数组的值是内存空间的任意值?
np.empty(3)
array([1., 1., 1.])

2.1.6 NumPy中标准数据类型

NumPy数组包含同一类型的值. NumPy是在C语言基础上开发的.
在构建数组时,可以用一个字符串参数指定数据类型
-NumPy中数据类型比Python中数据类型多,不加引号可能会报错
np.zeros(10, dtype='int16')
np.zeros(10,dtype=np.int16)
np.zeros(10,dtype=int)
np.zeros(10,dtype=int16)      # int16是NumPy中数据类型,报错
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-38-ff102d8e3e0a> in <module>()
      2 np.zeros(10,dtype=np.int16)
      3 np.zeros(10,dtype=int)
----> 4 np.zeros(10,dtype=int16)


NameError: name 'int16' is not defined
NumPy中数据类型
-bool_ : 布尔值
-int_ : 默认整型
-intc : 同C语言中int相同
-intp : 用作索引的整型
-int8 : 字节,范围从-128到127
-int16 :
-int32 :
-int64 :
-uint8 :
-uint16 :
-uint32 :
-uint64 :
-float_ :
-float16 :
-loat32 :
-float64 :
-complex_ :
-complex64 :
-complex128 :

2.2 NumPy数组基础

Python中数据操作几乎等同于NumPy中数组操作.Pandas工具也是构建在NumPy数组的基础之上的.
    -数组的属性(大小,形状,存储大小,数据类型)
    -数组的索引(获取或者设置各个元素的值)
    -数组的切分
    -数组的变形
    -数组的拼接与分裂

2.2.1 数组的属性

import numpy as np
np.random.seed(0)     #设置随机数种子值,
x1 = np.random.randint(10,size=6)    # 还可以写成 np.random.randint(0,10,6)
np.random.randint(0,10,6)
x2 = np.random.randint(10,size=(3,4))
x3 = np.random.randint(10,size=(3,4,5))
print(x3)
[[[4 3 0 3 5]
  [0 2 3 8 1]
  [3 3 3 7 0]
  [1 9 9 0 4]]

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

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

每个数组都有数组的ndim(数组的维度),shape(数组每个维度的大小),size(数组的总大小)和dtype(数组的数据类型)
其他: itemsize(每个元素字节大小), nbytes(总字节大小). 什么东东?

print('x3的维度是:',x3.ndim)
print('x3的每个维度大小是:',x3.shape)    # 每个维度的大小是从外向内数?
print('x3的总大小是:',x3.size)
print('x3的数据类型是:',x3.dtype)
print('x3的字节大小是:',x3.itemsize,"bytes")
print('x3的总字节大小是:',x3.nbytes,'bytes')
x3的维度是: 3
x3的每个维度大小是: (3, 4, 5)
x3的总大小是: 60
x3的数据类型是: int32
x3的字节大小是: 4 bytes
x3的总字节大小是: 240 bytes

2.2.2 数组的索引: 获取单个元素

一维数组

np.random.seed(0)
x1 = np.random.randint(10,size=6)     # 这样生成的6位随机数居然和书本上的一样
print(x1)
print(x1[0])                          #第一位
print(x1[4])
print(x1[-1])       #最后一位
[5 0 3 3 7 9]
5
7
9

二维数组

print(x2)
print(x2[0,0])
print(x2[2,2])
print(x2[2,-1])
[[8 8 1 6]
 [7 7 8 1]
 [5 9 8 9]]
8
8
9

修改某个值数据. 数组是有数据类型的, 如果加入的数值类型不一样, 会自动变换

x2[0,0] = "100"    #如果是字符型字符串则报错
x2[2,2] =  3.14
x2
array([[100,   8,   1,   6],
       [  7,   7,   8,   1],
       [  5,   9,   3,   9]])

三维数组

x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

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

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
print(x3[0,0,0])
print(x3[1,2,1])    # 二维 ,第3行,第2列
x3[1,2,1]=1000
print(x3)
4
8
[[[   4    3    0    3    5]
  [   0    2    3    8    1]
  [   3    3    3    7    0]
  [   1    9    9    0    4]]

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

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

2.2.3 数组的切片: 获取子数组

NumPy中切片语法和Python中列表的切片语法相同, 用冒号(:)分开.
x[start:stop:step]
如果以上三个参数都没有设置,则使用默认值 start=0, stop=维度的大小, 和step=1

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:5]   # 前5个
array([0, 1, 2, 3, 4])
x[5:]
array([5, 6, 7, 8, 9])
x[4:7]
array([4, 5, 6])

每隔一个数字

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

一维数组逆序

x[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

二维数组

x2
array([[8, 8, 1, 6],
       [7, 7, 8, 1],
       [5, 9, 8, 9]])
x2[:2,:3]     
array([[100,   8,   1],
       [  7,   7,   8]])

看见冒号(?,表示数组切片

x2[:,::2]   # 所有行, 每隔一列
array([[8, 1],
       [7, 8],
       [5, 8]])
x2[::-1,::-1]    # 颠倒顺序
array([[9, 8, 9, 5],
       [1, 8, 7, 7],
       [6, 1, 8, 8]])

三维数组

x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

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

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
x3[::-1,::-1,::-1]
array([[[   4,    8,    4,    4,    3],
        [   4,    4,    6,    4,    4],
        [   9,    5,    3,    0,    2],
        [   7,    6,    3,    9,    9]],

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

       [[   4,    0,    9,    9,    1],
        [   0,    7,    3,    3,    3],
        [   1,    8,    3,    2,    0],
        [   5,    3,    0,    3,    4]]])
x3
array([[[   4,    3,    0,    3,    5],
        [   0,    2,    3,    8,    1],
        [   3,    3,    3,    7,    0],
        [   1,    9,    9,    0,    4]],

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

       [[   9,    9,    3,    6,    7],
        [   2,    0,    3,    5,    9],
        [   4,    4,    6,    4,    4],
        [   3,    4,    4,    8,    4]]])
x3[::,0,::]   # 第一维度全选, 第二维度选第1行,第三维度全选
array([[4, 3, 0, 3, 5],
       [7, 3, 2, 7, 2],
       [9, 9, 3, 6, 7]])
x3[::2,::2,::2]
array([[[4, 0, 5],
        [3, 3, 0]],

       [[9, 3, 7],
        [4, 6, 4]]])

获取数组的单行或者单列

x2
array([[8, 8, 1, 6],
       [7, 7, 8, 1],
       [5, 9, 8, 9]])
x2[:,0]   # 第1列
array([8, 7, 5])
x2[:,2]  # 第3列
array([1, 8, 8])
x2[0,:]  # 第1行   
x2[0]    #获取行时简写表示方法, 对列不适用
array([8, 8, 1, 6])
x2[1,:]
array([7, 7, 8, 1])
NumPy数组切片和Python列表切片的不同之处: NumPy数组切片返回的是数组的试图,而不是数值数据的副本. 在Pythong列表中,切片是值得副本.
-副本 : 可以理解为复制了一份和原来的不一样了.
-视图 : 可以理解为超链接,修改还是改的原来的路径(文件)
-好处是,当处理大量的数据集时, 只需要修改切片即可修改原数据
print(x2)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]

从中抽取一个2*2的子数组

x2_sub = x2[::2,::2]
print(x2_sub)
[[100   1]
 [  5   8]]
x2_sub[0,0] = 100
x2
array([[100,   8,   1,   6],
       [  7,   7,   8,   1],
       [  5,   9,   8,   9]])
数组切片只能形成数组的视图, 那如果要新建副本,用copy()方法
x2_sub = x2[::2,::2].copy()
print(x2)
print('*'*20)
print(x2_sub)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]
********************
[[100   1]
 [  5   8]]
x2_sub[1,1] = 99
print(x2)
print("*"*20)
print(x2_sub)
print('*'*20)
print(x2)
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]
********************
[[100   1]
 [  5  99]]
********************
[[100   8   1   6]
 [  7   7   8   1]
 [  5   9   8   9]]

2.2.4 数组的变形

最常用的方法是用reshape()方法实现.
例如:期望将数字1-9,放入3*3的矩阵中,可采用如下方法:

-reshape()  数组的属性
-newaxis()  np的属性
np.arange(1,10).reshape(3*3)    #错
np.arange(1,10).reshape(3,3)
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
原始数组的大小必须和变形后数组大小一致. reshape返回原数组的一个视图

大小不一致的情况

a1 = ([1,2,3,4,5,6,7,8])
np.a1.reshape(3,3)     # 表示方法错. np没有a1属性
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-48-75353fe7632b> in <module>()
      1 a1 = ([1,2,3,4,5,6,7,8,9])
----> 2 np.a1.reshape(3,3)


AttributeError: module 'numpy' has no attribute 'a1'
a1 = array([1,2,3,4,5,6,7,8])    # 数组array 前面必须带np
a1.reshape((3,3))     
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-52-202d01b8f390> in <module>()
----> 1 a1 = array([1,2,3,4,5,6,7,8])
      2 a1.reshape((3,3))     # 表示方法错


NameError: name 'array' is not defined
a1 = np.array([1,2,3,4,5,6,7,8,9])
a1.reshape((3,3))     
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
np.array([1,2,3,4,5,6,7,8]).reshape(3,3)     # 少了不行
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-49-1a37bef6142d> in <module>()
----> 1 np.array([1,2,3,4,5,6,7,8]).reshape(3,3)


ValueError: cannot reshape array of size 8 into shape (3,3)
np.array([1,2,3,4,5,6,7,8,9,10]).reshape(3,3)  # 多了也不行
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-50-0a4d36c4b6a6> in <module>()
----> 1 np.array([1,2,3,4,5,6,7,8,9,10]).reshape(3,3)


ValueError: cannot reshape array of size 10 into shape (3,3)
x = np.array([1,2,3])   #一维数组
x.reshape(1,3)    #  变成1行3列的二维数组
array([[1, 2, 3]])
x[np.newaxis,:]
array([[1, 2, 3]])
x.reshape(3,1)
array([[1],
       [2],
       [3]])
x[:,np.newaxis]    # newaxis 属于关键字
array([[1],
       [2],
       [3]])

2.2.5 数组的拼接和分裂

多个数组合并成一个或者一个数组拆分成多个

-np.concatenate():将数组元组和数组列表作为第一个参数
-np.vstack()
-np.hstack()
x = np.array([1,2,3])
y = np.array([3,2,1])
x_y = np.concatenate([x,y])
print(x_y)
print(x_y.ndim)
[1 2 3 3 2 1]
1
z = [99,99,99]  # 不用 np.array([99,99,99])
np.concatenate([x,y,z])
array([ 1,  2,  3,  3,  2,  1, 99, 99, 99])
x1 = [99,99,99]   # 这是一个列表
x2 = np.array([99,99,99])
print(x1 == x2)
print(x1 is x2)
[ True  True  True]
False

二维数组的拼接

#沿着第一个轴拼接?   沿着第一个轴拼接,为什么是纵向
import numpy as np
x1 = np.array([[1,2,3],
               [4,5,6]])
np.concatenate([x1,x1])   # 中括号不能少
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
# 沿着第二个轴拼接, 沿着水平方向
np.concatenate([x1,x1],axis=1)    # 注意中括号和圆括号的位置
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
沿着固定维度处理数组时, 使用

np.vstack(垂直栈)
np.hstack(水平栈)函数更简洁 ??

x1 = np.array([1,2,3])
x2 = np.array([[9,8,7],
              [2,5,9]])
#垂直栈数组
np.vstack([x1,x2])
array([[1, 2, 3],
       [9, 8, 7],
       [2, 5, 9]])
#水平栈数组
x3 = np.array([[99],
              [99]])
np.hstack([x3,x2])
array([[99,  9,  8,  7],
       [99,  2,  5,  9]])
数组的分裂
-np.split()
-np.hsplit()
-np.vsplit()
x = [1,2,3,99,99,3,2,1]  # 这不是一个序列码
x1,x2,x3 = np.split(x,(3,5))    # 注意 x 和[3,5]的位置与括号,也可以用(3,5)
print(x1,x2,x3)
[1 2 3] [99 99] [3 2 1]
x1 = np.arange(16).reshape(4,4)
up,low = np.vsplit(x1,2)     # [2]也可以写成(2),也可以不加括号 ?
print(up)
print('*'*20)
print(low)
print('*'*20)
print(x1)
[[0 1 2 3]
 [4 5 6 7]]
********************
[[ 8  9 10 11]
 [12 13 14 15]]
********************
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
left,right = np.hsplit(x1,[2])     # 为什么此处的中括号必须 
print(left)
print('*'*20)
print(right)
[1 2]
********************
[3]
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

python技巧(数据分析及可视化)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值