《python数据科学》-Numpy

0 引言

大数据时代,一切决策的依据都是数据,数据处理和数据分析的重要性毋庸置疑。
本博客不会深入到numpy,pandas的matplotlib的源码,主要介绍常用的API和使用场景,主要参考资料来自官网。
NumPy中文官网: NumPy中文官网.
Pandas中文官网:Pandas中文官网.
Matplotlib中文官网:Matplotlib中文官网.
学习任何技术最好的资源就是官方网站,当然如果英文好的朋友,英文网站的效果最佳,中文翻译后难免会有歧义。

# 
import numpy as np
import pandas as pd
import matplotlib as plt
np.__version__
# '1.20.3'
pd.__version__
# '1.2.4'
plt.__version__
# '3.4.2'

1 NumPy

NumPy是使用Python进行科学计算的基础软件包。除其他外,它包括:

  • 功能强大的N维数组对象。
  • 精密广播功能函数。
  • 集成 C/C+和Fortran 代码的工具。
  • 强大的线性代数、傅立叶变换和随机数功能。

1.1 创建数组

# 1 np.empty(shape,[dtype]) 返回指定shape的数组,元素是根据内存随机的
n1 = np.empty((2,3),dtype='int32')
n1

# array([[         0,          0,          0],
#       [1071644672,          0, 1072693248]])

# 2 np.empty_like(ndarray,[dtype]) 返回与ndarray数组相同shape的数组,元素也是随机的
n2 = np.empty_like(n1)
n2 
# array([[         0, 1072693248,          0],
#       [1072693248,          0, 1072693248]])

# 3 np.eye(N) 返回一个对角线为1,其他位置都有0的二维数组
np.eye(4)
# array([[1., 0., 0., 0.],
#       [0., 1., 0., 0.],
#       [0., 0., 1., 0.],
#       [0., 0., 0., 1.]])

# 4 np.identity(N) 返回一个标识数组,效果与eye相同

# 5 np.ones(shape, [dtype]) # 返回指定形状的指定类型的数组,并填充为1
n1 = np.ones((3,4),dtype='int32')
n1
#array([[1, 1, 1, 1],
#       [1, 1, 1, 1],
#       [1, 1, 1, 1]])
# 6 np.ones_like(a, [dtype]) # 返回与a数组相同形状的数组,并且填充为1
n2 = np.ones_like(n1,dtype='float')
n2
#array([[1., 1., 1., 1.],
#       [1., 1., 1., 1.],
#       [1., 1., 1., 1.]])

# 7 np.zeros() np.zeros_like()与np.ones() np.ones_like() 相同

# 8 np.full(shape, full_value) 填充full value中的数据到shape中并返回
n1 = np.full((2,3), 5)
n1
#array([[5, 5, 5],
#      [5, 5, 5]])
# 9 np.full_like(a, full_value) 填充full value到与a相同形状的数组中并返回
n2 = np.full_like(n1,7)
n2
# array([[7, 7, 7],
#       [7, 7, 7]])

# 10 reshape  改变数组的形状 shape以元组的形式传参数
## 方式一: b = np.reshape(a,newshape)
a = np.arange(12)
b = np.reshape(a,(3,4))
b
# array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])

## 方式二:a.reshape(shape)
a.reshape((3,4))
a
# array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])

# 11 np.ravel(a) 返回一个连续的一维数组
a = np.arange(12).reshape((3,4))
np.ravel(a)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

# 12 ndarray.flat  # 返回一个迭代器
type(a.flat)
# numpy.flatiter

# 13 np.moveaxis(a,src,des) 将数组a的src轴移动到des轴,二维数组只有0轴和1轴,三维数组有0,1,2三根轴,以此类推
a = np.arange(12).reshape((3,4))
np.moveaxis(a,0,1) 或者 np.moveaxis(a,1,0)
#array([[ 0,  4,  8], 
#       [ 1,  5,  9],
#       [ 2,  6, 10],
#       [ 3,  7, 11]])
# 从输出结果可以看到,二维数组的横轴与纵轴交换了位置

# 14 np.swapaxes(a,axes1,axes2) 交换数组的两个轴 
np.swapaxes(a,0,1) # 返回值与moveaxis() api相同

1.1+ 创建数组random

# +1 np.random.rand(d0,d1,...) 返回标准的随机分布[0,1)
np.random.rand(3,4)
#array([[0.45825097, 0.40145903, 0.73421355, 0.73296766],
#       [0.63460903, 0.97759794, 0.7060251 , 0.10444119],
#       [0.75560894, 0.96608834, 0.35512846, 0.99682704]])

# +2 np.random.randn(d0,d1,...) 返回标准的正态分布,均值为0,方差为1
np.random.randn(3,4)
# array([[ 0.95871938, -2.85997519, -0.84536782, -0.30606499],
#       [ 0.04930978,  0.21062939,  0.66238318,  0.20502361],
#       [-2.4039988 , -1.81935625,  0.52349081, -2.37276337]])

# +3 np.random.randint(low[, high, size]) 返回[low, high)区间内size大小的整数
np.random.randint(1,10,(3,4))
#array([[2, 3, 5, 7],
#       [9, 1, 4, 8],
#      [4, 4, 7, 5]])

# +4 np.random.sample([size]) 返回[0,1.0)区间内的浮点数
# np.random.random([size])/ ranf([size]) / sample([size]) 这四个api相同
np.random.sample((3,4))
#array([[0.84235095, 0.07688947, 0.90903085, 0.58440727],
#       [0.09175167, 0.41449593, 0.67110254, 0.31718442],
#       [0.52603519, 0.56556646, 0.84109242, 0.89343526]])

# +5 np.random.choice(a[, size, replace, p]) 随机选择数据
# replace 是否原地替换
# p 与a相同元素个数的一维数组
a = np.array(['kobe','wade','james','paul'])
np.random.choice(a,3)
# array(['paul', 'paul', 'james'], dtype='<U5')

# +6 np.random.bytes(length)返回随机长度的字节
np.random.bytes(10)
# b'\xd0\xad"t$\x93Qg\xfc\x03'

# +7 np.random.seed()获取随机种子
np.random.seed(2)
np.random.rand(3,4)
# array([[0.4359949 , 0.02592623, 0.54966248, 0.43532239],
#       [0.4203678 , 0.33033482, 0.20464863, 0.61927097],
#       [0.29965467, 0.26682728, 0.62113383, 0.52914209]])
np.random.seed(2)
np.random.rand(3,4)
# array([[0.4359949 , 0.02592623, 0.54966248, 0.43532239],
#       [0.4203678 , 0.33033482, 0.20464863, 0.61927097],
#       [0.29965467, 0.26682728, 0.62113383, 0.52914209]])

# +8 np.random.suffle(x) 原地打乱数组x的次序
a = np.arange(12).reshape((3,4))
np.random.shuffle(a)
a 
#array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])

# +9 np.random.permutation(x) 打乱x次序后返回一个新的数组
a = np.arange(12).reshape((3,4))
b = np.random.permutation(a)
a,b  # a不变,打乱次序后返回给b
#(array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]]),
# array([[ 8,  9, 10, 11],
#        [ 4,  5,  6,  7],
#        [ 0,  1,  2,  3]]))

1.2 组合数组

# 15 np.concatenate((a1,a2...)) 沿现有轴连接数组
a = np.arange(12).reshape((3,4))
b = np.arange(12,24).reshape((3,4))
np.concatenate((a,b))
#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]])

# 16 np.vstack((a1,a2..)) 垂直合并数组,vertical 垂直
a = np.arange(12).reshape((3,4))
b = np.arange(12,24).reshape((3,4))
np.vstack((a,b))
#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]])

# 17 np.hstack((a1,a2...)) 水平合并数组, horizantal 水平
a = np.arange(12).reshape((3,4))
b = np.arange(12,24).reshape((3,4))
np.hstack((a,b))
#array([[ 0,  1,  2,  3, 12, 13, 14, 15],
#       [ 4,  5,  6,  7, 16, 17, 18, 19],
#       [ 8,  9, 10, 11, 20, 21, 22, 23]])

# 18 np.column_stack((a,b)) 将一维数组当成一列整合到二维数组中,一维数组的元素个数与二维数组的行数要匹配
a = np.arange(12).reshape((3,4))
c = np.array([77,88,99])
np.column_stack((c,a))

#array([[77,  0,  1,  2,  3],
#      [88,  4,  5,  6,  7],
#      [99,  8,  9, 10, 11]])

np.column_stack((a,c))
#array([[ 0,  1,  2,  3, 77],
#       [ 4,  5,  6,  7, 88],
#       [ 8,  9, 10, 11, 99]])

1.3 拆分数组

# 19 np.split(a, indices_or_sections)
"""
If indices_or_sections is an integer, N, the array will be divided into N equal arrays along axis. If such a split is not possible, an error is raised.
If indices_or_sections is a 1-D array of sorted integers, the entries indicate where along axis the array is split. For example, [2, 3] would, for axis=0, result in
      ary[:2]
      ary[2:3]
      ary[3:]
If an index exceeds the dimension of the array along axis, an empty sub-array is returned correspondingly.
"""
# 20 np.vsplit(a) 垂直分割
a = np.arange(12).reshape((4,6))
np.hsplit(a,[1,3]) # 水平方向分割 0~1 1~3 3: 
#[array([[ 0],
#        [ 6],
#        [12],
#        [18]]),
# array([[ 1,  2],
#        [ 7,  8],
#        [13, 14],
#       [19, 20]]),
# array([[ 3,  4,  5],
#        [ 9, 10, 11],
#        [15, 16, 17],
#        [21, 22, 23]])]

# 21 np.hsplit(a) 水平分割
a = np.arange(12).reshape((3,4))
np.hsplit(a,2)
#[array([[0, 1],
#        [4, 5],
#        [8, 9]]),
# array([[ 2,  3],
#        [ 6,  7],
#        [10, 11]])]

1.4 添加&删除元素

# 22 np.delete(arr, obj, axis=None) arr表示数组,obj可以是数字,列表,范围,axis表示轴,如果是None表示一个平铺的一维数组
a = np.arange(24).reshape((4,6))
np.delete(a,0,axis=0) # 删除数组a的第1行并返回
#array([[ 6,  7,  8,  9, 10, 11],
#       [12, 13, 14, 15, 16, 17],
#       [18, 19, 20, 21, 22, 23]])

np.delete(a,[0,2],axis=0)  # 删除数组a的第1行和第3行并返回
#array([[ 6,  7,  8,  9, 10, 11],
#       [12, 13, 14, 15, 16, 17]])

np.delete(a,[1,3,5],axis=None) # 删除1,3,5 元素
#array([ 0,  2,  4,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
#       20, 21, 22, 23]) 

np.delete(a,np.s_([::2]),axis=1) # 删除偶数列
#array([[ 1,  3,  5],
#       [ 7,  9, 11],
#       [13, 15, 17],
#       [19, 21, 23]])

# 23 np.insert(arr,obj,values,[axis]) axis默认为None,为None将arr打散成一维数组,将values插入到obj索引前,如果不为None,则按照axis的数值插入一行或者一列
a = np.arange(12).reshape((3,4))
np.insert(a,0,[66,77,88,99],None)
#array([66, 77, 88, 99,  1,  1,  1,  2,  2,  2,  3,  3,  3])
np.insert(a,0,[66,77,88,99],0)
#array([[66, 77, 88, 99],
#       [ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])
np.insert(a,0,[66,77,88],1)
#array([[66,  0,  1,  2,  3],
#       [77,  4,  5,  6,  7],
#       [88,  8,  9, 10, 11]])

# 24 np.unique(arr) 查找数组的唯一元素
a = np.array([[[1,1,1],[2,2,2],[3,3,3]]])
np.unique(a)
# array([1, 2, 3])

1.5 重排元素

# 25 np.flip(arr,[axis]) 沿指定轴颠倒数组中元素的位置
a=np.arange(12).reshape((3,4))
np.flip(a,axis=None)  # 元素合成一维数组后重排
#array([[11, 10,  9,  8],
#       [ 7,  6,  5,  4],
#       [ 3,  2,  1,  0]])

np.flip(a,axis=0) # 元素所有行重排
#array([[ 8,  9, 10, 11],
#       [ 4,  5,  6,  7],
#       [ 0,  1,  2,  3]])

np.flip(a,axis=1) # 元素所有列重排
#array([[ 3,  2,  1,  0],
#       [ 7,  6,  5,  4],
#       [11, 10,  9,  8]])
# 26 np.fliplr(arr) # 左右翻转数组
a=np.arange(12).reshape((3,4))
np.fliplr(a)
#array([[ 3,  2,  1,  0],
#       [ 7,  6,  5,  4],
#       [11, 10,  9,  8]])

# 27 np.flipud(arr) # 上下翻转数组
a=np.arange(12).reshape((3,4))
np.flipud(a)
#array([[ 8,  9, 10, 11],
#       [ 4,  5,  6,  7],
#       [ 0,  1,  2,  3]])

# 28 np.roll(arr,shift,[axis]) 沿指定轴滚动元素
# arr:需要滚动数据的数组
# shift :整数,可以正也可以负数
# axis : None 0 1 ... None表示将多维数组转换成一维数组
a=np.arange(12).reshape((3,4))
np.roll(a,1,None)
#array([[11,  0,  1,  2],
#       [ 3,  4,  5,  6],
#       [ 7,  8,  9, 10]])
np.roll(a,1,0)
#array([[ 8,  9, 10, 11],
#       [ 0,  1,  2,  3],
#       [ 4,  5,  6,  7]])
np.roll(a,1,1)
#array([[ 3,  0,  1,  2],
#       [ 7,  4,  5,  6],
#       [11,  8,  9, 10]])

# 29 np.rot90(arr) 在轴指定的平面中将阵列旋转90度
a=np.arange(12).reshape((3,4))
#array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])
np.rot90(a)
#array([[ 3,  7, 11],
#       [ 2,  6, 10],
#       [ 1,  5,  9],
#       [ 0,  4,  8]])

1.6 索引取值

# 30  一维数组切片
a = np.arange(10) 
方式一: slice(start,stop,step)
s = slice(0,-1,2)
a[s]
# array([0, 2, 4, 6, 8])
方式二:a[start:stop:step]
a[0:-1:2]
# array([0, 2, 4, 6, 8])
==:表示的数据范围含首不含尾 [start,stop)==

# 31 二维数组切片
a = np.arange(12).reshape((3,4))
a[1:] # 取第二行以后的所有值
#array([[ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])
a[...,1:] # 取所有行的第二列以后的所有值
#array([[ 1,  2,  3],
#       [ 5,  6,  7],
#       [ 9, 10, 11]])
a[2,3] # 获取第三行第四列的值
# 11
a[[0,2],...] # 获取第一行和第三行
#array([[ 0,  1,  2,  3],
#       [ 8,  9, 10, 11]])
a[[0,2],0]  # 获取第一行和第三行的第一列
# array([0, 8])

# 32 条件索引
# ~ 条件非  & 条件与  | 条件或  
a = np.arange(12)
a[a>5]
# array([ 6,  7,  8,  9, 10, 11])
a[(a>5)&(a<9)]
# array([6, 7, 8])
a[1] = np.nan

a[~np.isnan(a)]
# array([ 0.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.])

1.7 时间日期

numpy中使用datetime64存储时间日期数据类型
Y-年;M-月;W-周;D-天;h-时;m-分;s-秒;ms-毫秒;us-微秒;ns-纳秒;ps-皮秒;fs-飞秒;as-阿托秒

# 33 生成一个时间序列
np.arange('2020-03-01','2020-03-31',dtype='datetime64')
#array(['2020-03-01', '2020-03-02', '2020-03-03', '2020-03-04',
#       '2020-03-05', '2020-03-06', '2020-03-07', '2020-03-08',
#       '2020-03-09', '2020-03-10', '2020-03-11', '2020-03-12',
#       '2020-03-13', '2020-03-14', '2020-03-15', '2020-03-16',
#       '2020-03-17', '2020-03-18', '2020-03-19', '2020-03-20',
#       '2020-03-21', '2020-03-22', '2020-03-23', '2020-03-24',
#       '2020-03-25', '2020-03-26', '2020-03-27', '2020-03-28',
#      '2020-03-29', '2020-03-30'], dtype='datetime64[D]')

# 34 从字符串转换成时间序列后,如果字符串格式不统一,则按照最小的单位
np.array(['2021-03','2021-03-01','2021-03-02 20:00'],dtype='datetime64')
#array(['2021-03-01T00:00', '2021-03-01T00:00', '2021-03-02T20:00'],
#      dtype='datetime64[m]')

# 35 时间运算
#方式一:
np.datetime64('2021-07-01','D')-np.datetime64('2021-06-01','D')
# numpy.timedelta64(30,'D')
np.datetime64('2021-07-01','M')-np.datetime64('2021-06-01','M')
# numpy.timedelta64(1,'M')
np.datetime64('2021-07-01','m')-np.datetime64('2021-06-01','m')
numpy.timedelta64(43200,'m')
#方式二:
np.datetime64('2021-07-01','m')+np.timedelta64(10,'D')
# numpy.datetime64('2021-07-11T00:00')
np.datetime64('2021-07-01','m')-np.timedelta64(100,'m')
# numpy.datetime64('2021-06-30T22:20') 

# 36 np.datetime64与datetime.datetime之间相互转换
from datetime import datetime 
dt = datetime(year=2021,month=7,day=4,hour=20,minute=10,second=30)
np.datetime64(dt)
# numpy.datetime64('2021-07-04T20:10:30.000000')
dt64.astype(datetime)
# datetime.datetime(2021, 7, 4, 20, 10, 30)

# 37 np.is_busday(dates,weekmask)
np.is_busday('2021-07-04',weekmask=[0,0,0,0,0,1,1])
# True
np.is_busday('2021-07-04') # weekmask默认时1111100
# False

# 38 np.count_nonzero() 统计一段时间内工作日的数量,获取数组内true的数量
start_date = '2021-07-01'
end_date = '2021-07-31'
date_range = np.arange(start_date,end_date,dtype='datetime64')
np.count_nonzero(np.is_busday(date_range))

# 39 np.busday_offset(date,offsets, roll, weekmarks) 取当前日期的下一个工作日
# 2021-07-02 星期五
np.busday_offset('2021-07-02',offsets=1,roll='forward')
# numpy.datetime64('2021-07-05')
np.busday_offset('2021-07-05',offsets=-1,roll='backward')
# numpy.datetime64('2021-07-02')

1.8 统计

# 40 np.median(arr,[axis]) 求中位数
a = np.arange(32).reshape((4,8))
np.median(a,axis=None)
# 15.5
np.median(a,axis=0)
# array([12., 13., 14., 15., 16., 17., 18., 19.])
np.median(a,axis=1)
# array([ 3.5, 11.5, 19.5, 27.5])

# 41 np.average(arr,[axis]) 算数平均值
# 42 np.mean(arr,[axis]) 加权平均值
# 43 np.std(arr,[axis]) 标准差
# 44 np.var(arr,[axis]) 方差
# 45 nanmedian,nanmean,nanstd,nanvar 忽略nan值

# 46 histogram(a,bins=10,range=None,weights=None,density=False);
"""
    a是待统计数据的数组;

    bins指定统计的区间个数;

    range是一个长度为2的元组,表示统计范围的最小值和最大值,默认值None,表示范围由数据的范围决定

    weights为数组的每个元素指定了权值,histogram()会对区间中数组所对应的权值进行求和

    density为True时,返回每个区间的概率密度;为False,返回每个区间中元素的个数
"""
a = np.random.rand(100)
count,bins = np.histogram(a, bins=5, range=(0,1))
count,bins # bins将a中的数据分成5段,0~0.2有23个,0.2~0.4有19个 count是统计数组中在每个段内的数量
#(array([23, 23, 19, 16, 19], dtype=int64),
# array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kobe_OKOK_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值