欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python数据分析与挖掘学习笔记二:Numpy

程序员文章站 2022-05-28 19:38:04
...

用于处理任意维度的数组

Numpy(Numerical Python)是一个开源的Python科学计算基础库,包含: 

  •  一个强大的N维数组对象 ndarray 
  • 广播功能函数 
  • 整合C/C++/Fortran代码的工具 
  • 线性代数、傅里叶变换、随机数生成等功能
  • 同时Numpy是SciPy、 Pandas等数据处理或科学计算库的基础

numpy与Python原生list相比的优势

numpy数组在数值运算方面的效率优于Python提供的list容器。

  1. 内存结构           存储在内存中的一块联系存储区域,提高了数据的读取效率
  2. 并行运算
  3. 底层是用C语言编写的, 解放了GIL锁, 不受Python解释器的限制
import numpy as np
# 定义一个二维数组, dtype 定义类型
arr = np.array([[1,2,3],[3,4,4]],dtype=int)
print(arr)

数组的属性:

属性名字

属性解释

ndarray.shape

数组的形状,是一个元组,元素个数与维度相同

ndarray.ndim

数组维数

ndarray.size

数组中的元素数量

ndarray.itemsize

一个数组元素的长度(字节)

ndarray.dtype

数组元素的类型

 

数组的类型:

名称 描述 简写
np.bool 用一个字节存储的布尔类型(True或False) 'b'
np.int8 一个字节大小,-128 至 127 'i'
np.int16 整数,-32768 至 32767 'i2'
np.int32 整数,-2 31 至 2 32 -1 'i4'
np.int64 整数,-2 63 至 2 63 - 1 'i8'
np.uint8 无符号整数,0 至 255 'u'
np.uint16 无符号整数,0 至 65535 'u2'
np.uint32 无符号整数,0 至 2 ** 32 - 1 'u4'
np.uint64 无符号整数,0 至 2 ** 64 - 1 'u8'
np.float16 半精度浮点数:16位,正负号1位,指数5位,精度10位 'f2'
np.float32 单精度浮点数:32位,正负号1位,指数8位,精度23位 'f4'
np.float64 双精度浮点数:64位,正负号1位,指数11位,精度52位 'f8'
np.complex64 复数,分别用两个32位浮点数表示实部和虚部 'c8'
np.complex128 复数,分别用两个64位浮点数表示实部和虚部 'c16'
np.object_ python对象 'O'
np.string_ 字符串 'S'
np.unicode_ unicode类型 'U'
>>> a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
>>> a.dtype
dtype('float32')

注意:若不指定,整数默认int64,小数默认float64

生成数组的方式:

1 生成0和1的数组

  • empty(shape[, dtype, order]) empty_like(a[, dtype, order, subok])
    eye(N[, M, k, dtype, order])
  • identity(n[, dtype])
  • ones(shape[, dtype, order])
  • ones_like(a[, dtype, order, subok])
  • zeros(shape[, dtype, order]) zeros_like(a[, dtype, order, subok])
    full(shape, fill_value[, dtype, order])
  • full_like(a, fill_value[, dtype, order, subok])
>>> zero = np.zeros([3, 4])
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

2 从现有数组生成

  • array(object[, dtype, copy, order, subok, ndmin])

  • asarray(a[, dtype, order])

  • asanyarray(a[, dtype, order]) ascontiguousarray(a[, dtype])
  • asmatrix(data[, dtype])
  • copy(a[, order])
a = np.array([[1,2,3],[4,5,6]])
# 从现有的数组当中创建
a1 = np.array(a)
# 相当于索引的形式,并没有真正的创建一个新的
a2 = np.asarray(a)

关于array和asarray的不同

array是深拷贝  asarray 是浅拷贝

3 生成固定范围的数组

  • np.linspace (start, stop, num, endpoint, retstep, dtype)

生成等间隔的序列

start 序列的起始值
stop 序列的终止值,
如果endpoint为true,该值包含于序列中
num 要生成的等间隔样例数量,默认为50
endpoint 序列中是否包含stop值,默认为ture
retstep 如果为true,返回样例,
以及连续数字之间的步长
dtype 输出ndarray的数据类型
# 生成等间隔的数组
np.linspace(0, 100, 10)

返回结果:

array([  0.        ,  11.11111111,  22.22222222,  33.33333333,
        44.44444444,  55.55555556,  66.66666667,  77.77777778,
        88.88888889, 100.        ])
  • 其它的还有
    • numpy.arange(start,stop, step, dtype)
    • numpy.logspace(start,stop, num, endpoint, base, dtype)
np.arange(10, 50, 2)

返回结果:

array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
       44, 46, 48])

4 生成随机数组

  • np.random模块

    • 均匀分布

      • np.random.rand(d0d1...dn)

        返回[0.0,1.0)内的一组均匀分布的数。

      • np.random.uniform(low=0.0high=1.0size=None)

        功能:从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开,即包含low,不包含high.

        参数介绍:

        low: 采样下界,float类型,默认值为0;

        high: 采样上界,float类型,默认值为1;

        size: 输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出mnk个样本,缺省时输出1个值。

        返回值:ndarray类型,其形状和参数size中描述一致。

      • np.random.randint(lowhigh=Nonesize=Nonedtype='l')

        从一个均匀分布中随机采样,生成一个整数或N维整数数组,取数范围:若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。

# 生成均匀分布的随机数
x1 = np.random.uniform(-1, 1, 100000000)

返回结果:

array([ 0.22411206,  0.31414671,  0.85655613, ..., -0.92972446,
0.95985223,  0.23197723])

画图看分布状况:

import matplotlib.pyplot as plt

# 生成均匀分布的随机数
x1 = np.random.uniform(-1, 1, 100000000)

# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(10, 10), dpi=100)

# 2)绘制直方图
plt.hist(x1, 1000)

# 3)显示图像
plt.show()

 

  • 正态分布

    • np.random.randn(d0, d1, …, dn)

      功能:从标准正态分布中返回一个或多个样本值

    • np.random.normal(loc=0.0scale=1.0size=None)

      loc:float

      ​ 此概率分布的均值(对应着整个分布的中心centre)

      scale:float

      ​ 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)

      size:int or tuple of ints

      ​ 输出的shape,默认为None,只输出一个值

    • np.random.standard_normal(size=None)

      返回指定形状的标准正态分布的数组。

正态分布(理解)

1 什么是正态分布

正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的方差,所以正态分布记作N(μ,σ )

2 正态分布的应用

生活、生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述。

3 正态分布特点

μ决定了其位置,其标准差σ。决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布。

标准差如何来?

方差

在概率论和统计学中衡量一组数据离散程度的度量

 

其中M为平均值,n为数据总个数,S为标准差,S^2可以理解一个整体为方差

标准差与方差的意义

可以理解成数据的一个离散程度的衡量

x2 = np.random.normal(1.75, 1, 100000000)

返回结果:

array([2.90646763, 1.46737886, 2.21799024, ..., 1.56047411, 1.87969135,
       0.9028096 ])
# 生成均匀分布的随机数
x2 = np.random.normal(1.75, 1, 100000000)

# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(20, 10), dpi=100)

# 2)绘制直方图
plt.hist(x2, 1000)

# 3)显示图像
plt.show()

Python数据分析与挖掘学习笔记二:Numpy

例如:我们可以模拟生成一组股票的涨跌幅的数据

案例:随机生成8只股票2周的交易日涨幅数据

8只股票,两周(10天)的涨跌幅数据,如何获取?

  • 两周的交易日数量为:2 X 5 =10
  • 随机生成涨跌幅在某个正态分布内,比如均值0,方差1

股票涨跌幅数据的创建

# 创建符合正态分布的8只股票10天的涨跌幅数据
stock_change = np.random.normal(0, 1, (8, 10))
stock_change

返回结果:

array([[-0.03862668, -1.46128096, -0.75596237,  0.89737022, -1.86978433,
         0.38845392,  1.14856354, -1.10912275,  1.28900021, -0.86801677],
       [ 1.8701446 ,  0.50407342, -0.74396489, -1.69641331, -0.89969227,
         2.42459765,  0.78987443, -0.82935223,  0.82546455,  0.40524289],
       [-1.7365776 , -0.81501515, -1.08974743, -1.4138561 ,  0.85495155,
         0.30076624, -2.0813311 ,  1.52886975,  0.62945643, -1.48714683],
       [-1.12084983, -0.63070289, -0.20677245, -0.49096973, -0.40551104,
        -0.46320893, -0.73190969,  0.00392486,  2.524498  ,  0.25843191],
       [ 0.05001371,  0.52267878,  1.31974783,  0.64840953,  1.56360431,
        -0.79233575,  1.47275167,  0.61070343, -0.33247221, -0.57492172],
       [ 0.7092757 ,  0.00928591,  0.27008373,  0.79050681, -0.95887888,
         0.03661459,  0.81303927, -0.54139691,  0.69623969,  0.06570421],
       [-1.40481949,  0.49151272,  1.01992235,  1.89152928, -0.76415623,
         0.3100241 ,  1.27156806, -1.76199057, -0.77419965, -0.17574386],
       [-0.21745814, -1.78433763, -0.7953073 ,  0.4765644 , -0.2589575 ,
         0.97014013,  1.67321489,  1.73370987,  0.29886514,  1.27186522]])

数组的索引、切片

  • 获取第一个股票的前3个交易日的涨跌幅数据
# 二维的数组,两个维度 
stock_change[0, 0:3]

返回结果:

array([-0.03862668, -1.46128096, -0.75596237])

一维、二维、三维的数组如何索引?

# 三维,一维
a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
# 返回结果
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[12,  3, 34],
        [ 5,  6,  7]]])
# 索引、切片
>>> a1[0, 0, 1]   # 输出: 2

形状修改

需求:让刚才的股票行、日期列反过来,变成日期行,股票列

  • ndarray.reshape(shape[, order]) Returns an array containing the same data with a new shape.
# 在转换形状的时候,一定要注意数组的元素匹配
stock_change.reshape([10, 8]) # 只是将形状进行了修改,但并没有将行列进行转换
stock_change.reshape([-1,20])  # 数组的形状被修改为: (4, 20), -1: 表示通过待计算
  • ndarray.T 数组的转置
    • 将数组的行、列进行互换
stock_change.shape
(8, 10)
stock_change.T.shape
(10, 8)
  • ndarray.resize(new_shape[, refcheck]) Change shape and size of array in-place.
stock_change.resize([10, 8])

3.3.4 类型修改

  • ndarray.astype(type)
stock_change.astype(np.int32)
  • ndarray.tostring([order])或者ndarray.tobytes([order]) Construct Python bytes containing the raw data bytes in the array.
    • 转换成bytes
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
arr.tostring()

拓展:如果遇到

IOPub data rate exceeded.
    The notebook server will temporarily stop sending output
    to the client in order to avoid crashing it.
    To change this limit, set the config variable
    `--NotebookApp.iopub_data_rate_limit`.

这个问题是在jupyer当中对输出的字节数有限制,需要去修改配置文件

创建配置文件

jupyter notebook --generate-config
vi ~/.jupyter/jupyter_notebook_config.py

取消注释,多增加

## (bytes/sec) Maximum rate at which messages can be sent on iopub before they
#  are limited.
c.NotebookApp.iopub_data_rate_limit = 10000000

但是不建议这样去修改,jupyter输出太大会崩溃

3.3.5 数组的去重

  • ndarray.unique
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
>>> np.unique(temp)
array([1, 2, 3, 4, 5, 6])

ndarray运算

np.all()

# 判断stock_change[0:2, 0:5]是否全是上涨的>>> np.all(stock_change[0:2, 0:5] > 0)False

np.any()

# 判断前5只股票这段期间是否有上涨的>>> np.any(stock_change[0:5, :] > 0 )True

三元运算符np.where

# 判断前四个股票前四天的涨跌幅 大于0的置为1,否则为0

temp = stock_change[:4, :4]

np.where(temp > 0, 1, 0)

统计指标:

min(a[, axis, out, keepdims])  最小值

          Return the minimum of an array or minimum along an axis.

max(a[, axis, out, keepdims]) 最大值

         Return the maximum of an array or maximum along an axis.

median(a[, axis, out, overwrite_input, keepdims]) 中间值

         Compute the median along the specified axis.

mean(a[, axis, dtype, out, keepdims]) 平均数

         Compute the arithmetic mean along the specified axis.

std(a[, axis, dtype, out, ddof, keepdims])标准差 

         Compute the standard deviation along the specified axis.

var(a[, axis, dtype, out, ddof, keepdims])方差

         Compute the variance along the specified axis.

axis 轴的取值并不一定,Numpy中不同的API轴的值都不一样,在这里,axis 0代表列, axis 1代表行去进行统计

数组的运算 
 

np.abs(a) np.fabs(a) : 取各元素的绝对值 
np.sqrt(a) : 计算各元素的平方根 
np.square(a): 计算各元素的平方 
np.log(a) np.log10(a) np.log2(a) : 计算各元素的自然对数、10、2为底的对数 
np.ceil(a) np.floor(a) : 计算各元素的ceiling 值, floor值(ceiling向上取整,floor向下取整) 
np.rint(a) : 各元素 四舍五入 
np.modf(a) : 将数组各元素的小数和整数部分以两个独立数组形式返回 
np.exp(a) : 计算各元素的指数值 
np.sign(a) : 计算各元素的符号值 1(+),0,-1(-) 
np.maximum(a, b) np.fmax() : 比较(或者计算)元素级的最大值 
np.minimum(a, b) np.fmin() : 取最小值 
np.mod(a, b) : 元素级的模运算 
np.copysign(a, b) : 将b中各元素的符号赋值给数组a的对应元素
  • 数据的CSV文件存取
CSV (Comma-Separated Value,逗号分隔值) 只能存储一维和二维数组

np.savetxt(frame, array, fmt=’% .18e’, delimiter = None): frame是文件、字符串等,可以是.gz .bz2的压缩文件; array 表示存入的数组; fmt 表示元素的格式 eg: %d % .2f % .18e ; delimiter: 分割字符串,默认是空格 
eg: np.savetxt(‘a.csv’, a, fmt=%d, delimiter = ‘,’ )

np.loadtxt(frame, dtype=np.float, delimiter = None, unpack = False) : frame是文件、字符串等,可以是.gz .bz2的压缩文件; dtype:数据类型,读取的数据以此类型存储; delimiter: 分割字符串,默认是空格; unpack: 如果为True, 读入属性将分别写入不同变量。 
多维数据的存取 
a.tofile(frame, sep=’’, format=’%s’ ) : frame: 文件、字符串; sep: 数据分割字符串,如果是空串,写入文件为二进制 ; format:: 写入数据的格式 
eg: a = np.arange(100).reshape(5, 10, 2) 
a.tofile(“b.dat”, sep=”,”, format=’%d’)

np.fromfile(frame, dtype = float, count=-1, sep=’’): frame: 文件、字符串 ; dtype: 读取的数据以此类型存储; count:读入元素个数, -1表示读入整个文件; sep: 数据分割字符串,如果是空串,写入文件为二进制

PS: a.tofile() 和np.fromfile()要配合使用,要知道数据的类型和维度。

np.save(frame, array) : frame: 文件名,以.npy为扩展名,压缩扩展名为.npz ; array为数组变量 
np.load(fname) : frame: 文件名,以.npy为扩展名,压缩扩展名为

np.save() 和np.load() 使用时,不用自己考虑数据类型和维度。
  • numpy随机数函数
numpy 的random子库

rand(d0, d1, …,dn) : 各元素是[0, 1)的浮点数,服从均匀分布 
          randn(d0, d1, …,dn):标准正态分布 
          randint(low, high,( shape)): 依shape创建随机整数或整数数组,范围是[ low, high) 
         seed(s) : 随机数种子

shuffle(a) : 根据数组a的第一轴进行随机排列,改变数组a 
        permutation(a) : 根据数组a的第一轴进行随机排列, 但是不改变原数组,将生成新数组 
       choice(a[, size, replace, p]) : 从一维数组a中以概率p抽取元素, 形成size形状新数组,replace表示是否可以重用元素,默认为False。 


eg: Python数据分析与挖掘学习笔记二:Numpy 

replace = False时,选取过的元素将不会再选取

uniform(low, high, size) : 产生均匀分布的数组,起始值为low,high为结束值,size为形状 
normal(loc, scale, size) : 产生正态分布的数组, loc为均值,scale为标准差,size为形状 
poisson(lam, size) : 产生泊松分布的数组, lam随机事件发生概率,size为形状 
eg: a = np.random.uniform(0, 10, (3, 4)) a = np.random.normal(10, 5, (3, 4))
  • numpy的统计函数
sum(a, axis = None) : 依给定轴axis计算数组a相关元素之和,axis为整数或者元组 
mean(a, axis = None) : 同理,计算平均值 
average(a, axis =None, weights=None) : 依给定轴axis计算数组a相关元素的加权平均值 
std(a, axis = None) :同理,计算标准差 
var(a, axis = None): 计算方差 
eg: np.mean(a, axis =1) : 对数组a的第二维度的数据进行求平均 
a = np.arange(15).reshape(3, 5) 
np.average(a, axis =0, weights =[10, 5, 1]) : 对a第一各维度加权求平均,weights中为权重,注意要和a的第一维匹配

min(a) max(a) : 计算数组a的最小值和最大值 
argmin(a) argmax(a) : 计算数组a的最小、最大值的下标(注:是一维的下标) 
unravel_index(index, shape) : 根据shape将一维下标index转成多维下标 
ptp(a) : 计算数组a最大值和最小值的差 
median(a) : 计算数组a中元素的中位数(中值) 
eg:a = [[15, 14, 13], 
[12, 11, 10] ] 
np.argmax(a) –> 0 
np.unravel_index( np.argmax(a), a.shape) –> (0,0)
  • numpy的梯度函数

np.gradient(a) : 计算数组a中元素的梯度,f为多维时,返回每个维度的梯度 
           离散梯度: xy坐标轴连续三个x轴坐标对应的y轴值:a, b, c 其中b的梯度是(c-a)/2 
           而c的梯度是: (c-b)/1

当为二维数组时,np.gradient(a) 得出两个数组,第一个数组对应最外层维度的梯度,第二个数组对应第二层维度的梯度。 
Python数据分析与挖掘学习笔记二:Numpy

  • 图像的表示和变换
PIL, python image library 库 
from PIL import Image 
Image是PIL库中代表一个图像的类(对象)

im = np.array(Image.open(“.jpg”))

im = Image.fromarray(b.astype(‘uint8’)) # 生成 
im.save(“路径.jpg”) # 保存

im = np.array(Image.open(“.jpg”).convert(‘L’)) # convert(‘L’)表示转为灰度图

合并

  • numpy.concatenate((a1, a2, ...), axis=0)
  • numpy.hstack(tup) Stack arrays in sequence horizontally (column wise).
  • numpy.vstack(tup) Stack arrays in sequence vertically (row wise).

示例:

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> np.concatenate((a, b.T), axis=1)
array([[1, 2, 5],
       [3, 4, 6]])
>>> a = np.array((1,2,3))
>>> b = np.array((2,3,4))
>>> np.hstack((a, b))
array([1, 2, 3, 2, 3, 4])
>>> a = np.array([[1],[2],[3]])
>>> b = np.array([[2],[3],[4]])
>>> np.hstack((a, b))
array([[1, 2],
       [2, 3],
       [3, 4]])
>>> a = np.array([1, 2, 3])
>>> b = np.array([2, 3, 4])
>>> np.vstack((a, b))
array([[1, 2, 3],
       [2, 3, 4]])

>>> a = np.array([[1], [2], [3]])
>>> b = np.array([[2], [3], [4]])
>>> np.vstack((a, b))
array([[1],
       [2],
       [3],
       [2],
       [3],
       [4]])

比如我们将两部分股票的数据拼接在一起:

a = stock_change[:2, 0:4]
b = stock_change[4:6, 0:4]
# axis=1时候,按照数组的列方向拼接在一起
# axis=0时候,按照数组的行方向拼接在一起
np.concatenate([a, b], axis=0)
# np.hstack([a, b])
np.vstack([a, b])

分割

  • numpy.split(ary, indices_or_sections, axis=0) Split an array into multiple sub-arrays.
>>> x = np.arange(9.0)
>>> np.split(x, 3)
[array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.,  8.])]
>>> x = np.arange(8.0)
>>> np.split(x, [3, 5, 6, 10])
[array([ 0.,  1.,  2.]),
 array([ 3.,  4.]),
 array([ 5.]),
 array([ 6.,  7.]),
 array([], dtype=float64)]
# 将ab分割成3个样本
np.split(ab, 3)

返回结果:

[array([[ 1.10449299, -0.87901717,  1.66943952, -0.28083391]]),
 array([[ 1.7428746 ,  0.69109283, -1.7336799 ,  0.31330138]]),
 array([[-0.34175246,  0.05445987,  0.54143572, -1.50094197]])]
相关标签: Numpy