Haste makes waste

PythonDataAnalysis-02-Numpy数据存取与函数

Posted on By lijun

[PythonDataAnalysis-XX…]系列,参考Python数据分析与展示 嵩天@北京理工

根据第三方库内容特点,课程共分8个内容单元和4个实战单元:

  • 单元1:NumPy库入门:一维、二维、N维、高维数据表示和操作
  • 单元2:NumPy数据存取与函数:多维数据存储、随机数函数、统计函数、梯度函数
  • 单元3:实战:图像的手绘效果
  • 单元4:Matplotlib库的入门和基本使用
  • 单元5:Matplotlib基础绘图函数:饼图、直方图、极坐标图、散点图
  • 单元6:实战:引力波的绘制
  • 单元7:Pandas库入门:Series、DataFrame类型、基本操作
  • 单元8:Pandas数据特征分析:数据排序、基本统计分析、累计分析、相关分析

atom突然暴走,导致我这篇blog要重写,提醒再提醒一定要云同步,就当是复习一下吧。

1. csv文件的存取

CSV是一种常见的文件格式,用来存储批量数据。下面是操作CSV的两个主要函数:

  • np.savetxt(frame, array, fmt=’%.18e’, delimiter=None)
  • np.loadtxt(frame, dtype=np.float, delimiter=None, unpack=False)
    1. frame : 文件、字符串或产生器,可以是.gz或.bz2的压缩文件
    2. array : 存入文件的数组
    3. fmt : 写入文件的格式,例如:%d %.2f %.18e
    4. delimiter : 分割字符串,默认是任何空格
    5. dtype : 数据类型,可选
    6. unpack : 如果True,读入属性将分别写入不同变量
  • 示例:
In [4]: import numpy as np

In [5]: a = np.arange(50).reshape(5,10)

In [6]: a
Out[6]:
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, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])

In [8]: np.savetxt('a.csv',a,fmt='%d',delimiter=',')

In [9]: np.savetxt('b.csv',a,fmt='%.1f',delimiter=',')


In [12]: b = np.loadtxt('b.csv',dtype=np.int,delimiter=',')

In [13]: b
Out[13]:
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, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])

In [14]:

  1. a.csv是一个5行10列的不带小数点数字的csv文件,而b.csv输入的格式为.1f,带1个小数点的csv文件。
  2. 通过load将b.csv输出时,可以指定dtype为int。

2. 多维数据的存取

CSV只能有效存储一维和二维数组,np.savetxt() np.loadtxt()只能有效存取一维和二维数组。

2.1 任意维度的存取(不存储维度信息)

因为不能存储维度信息,所以通常的做法是一同存储另一个文件,写如维度信息,数据类型信息等。

  • a.tofile(frame, sep=’’, format=’%s’)
  • a.tofile(frame, sep=’’, format=’%s’)
    1. frame : 文件、字符串
    2. sep : 数据分割字符串,如果是空串,写入文件为二进制
    3. format : 写入数据的格式
    4. dtype : 读取的数据类型
    5. count : 读入元素个数,‐1表示读入整个文件

In [15]: a = np.arange(100).reshape(5,10,2)

# 写为普通文本文件,逗号分隔
In [17]: a.tofile('b.dat',sep=',',format='%d')
# 写为二进制文件
In [18]: a.tofile('c.dat',format='%d')

In [22]: b = np.fromfile('b.dat',dtype=np.int,sep=',')

In [23]: b
Out[23]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        ...
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])

In [26]: b.reshape(5,2,10)
Out[26]:
array([[[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
      [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]],
      ...
      [[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
      [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]]])
  • 通过loadtxt取出的数据被降为一维了,因为无法从dat文件中取得维度信息。

2.2 通过numpy自定义文件进行存储(带维度信息)

  • np.save(fname, array) 或 np.savez(fname, array)
  • np.load(fname)
    1. fname : 文件名,以.npy为扩展名,压缩扩展名为.npz
    2. array : 数组变量

存储方式与之前类似,就不代码举例子了。 下面是dat文件与npy文件的区别:npy文件只是在dat文件基础上添加了文件头而已。

image

3. NumPy的随机函数

3.1 NumPy的随机函数(1)

  • rand(d0,d1,..,dn): 根据d0‐dn创建随机数数组,浮点数,[0,1),均匀分布
  • randn(d0,d1,..,dn): 根据d0‐dn创建随机数数组,标准正态分布
  • randint(low[,high,shape]): 根据shape创建随机整数或整数数组,范围是[low, high)
  • seed(s): 随机数种子,s是给定的种子值
In [28]: a = np.random.rand(2,3,4)

In [29]: a
Out[29]:
array([[[ 0.06833491,  0.96329969,  0.68828102,  0.20019412],
        [ 0.86599309,  0.66552467,  0.46235502,  0.59537227],
        [ 0.4918919 ,  0.31891313,  0.97603906,  0.68231384]],

       [[ 0.54207048,  0.22137356,  0.18929645,  0.36846787],
        [ 0.76411345,  0.40699583,  0.66397333,  0.20063353],
        [ 0.02432712,  0.8464047 ,  0.15844467,  0.07179088]]])

# 两次生成的a不同
In [30]: a = np.random.rand(2,3,4)

In [31]: a
Out[31]:
array([[[ 0.51906316,  0.46229481,  0.27655783,  0.21399252],
        [ 0.36331412,  0.99366248,  0.0042362 ,  0.00114745],
        [ 0.14482473,  0.40346036,  0.34004555,  0.96238115]],

       [[ 0.66011009,  0.98879199,  0.21731108,  0.28719154],
        [ 0.85643879,  0.63221968,  0.08056116,  0.61968381],
        [ 0.68478896,  0.07636695,  0.81527296,  0.07379188]]])
In [33]: np.random.seed(10)

In [34]: a = np.random.rand(2,3,4)

In [35]: a
Out[35]:
array([[[ 0.77132064,  0.02075195,  0.63364823,  0.74880388],
        [ 0.49850701,  0.22479665,  0.19806286,  0.76053071],
        [ 0.16911084,  0.08833981,  0.68535982,  0.95339335]],

       [[ 0.00394827,  0.51219226,  0.81262096,  0.61252607],
        [ 0.72175532,  0.29187607,  0.91777412,  0.71457578],
        [ 0.54254437,  0.14217005,  0.37334076,  0.67413362]]])

# 设定随机数种子后两次生成的a是一样的
In [36]: np.random.seed(10)

In [37]: a = np.random.rand(2,3,4)

In [38]: a
Out[38]:
array([[[ 0.77132064,  0.02075195,  0.63364823,  0.74880388],
        [ 0.49850701,  0.22479665,  0.19806286,  0.76053071],
        [ 0.16911084,  0.08833981,  0.68535982,  0.95339335]],

       [[ 0.00394827,  0.51219226,  0.81262096,  0.61252607],
        [ 0.72175532,  0.29187607,  0.91777412,  0.71457578],
        [ 0.54254437,  0.14217005,  0.37334076,  0.67413362]]])

3.2 NumPy的随机函数(2)

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

如下的a会被改变,如果不能被改变可以使用b=np.random.permutation(a)

In [52]: a
Out[52]:
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, 32, 33, 34],
        [35, 36, 37, 38, 39],
        [40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49]]])

In [53]: np.random.shuffle(a)

In [54]: a
Out[54]:
array([[[25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39],
        [40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49]],

       [[ 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]]])
# 产生一个100,200之间的一维数组,长度为10
In [64]: b = np.random.randint(100,200,(10,))

In [65]: b
Out[65]: array([188, 111, 117, 146, 107, 175, 128, 133, 184, 196])

# 取随机数,组成一个2行3列的二维数组
In [66]: np.random.choice(b,(2,3))
Out[66]:
array([[184, 175, 107],
       [133, 184, 184]])

# 去随机数,不允许重复
In [67]: np.random.choice(b,(2,3),replace=False)
Out[67]:
array([[133, 107, 111],
       [146, 184, 175]])

# 取随机数,以p为概率,b的值越大则概率越大
In [68]: np.random.choice(b,(2,3),p=b/np.sum(b))
Out[68]:
array([[188, 184, 111],
       [107, 196, 196]])

3.3 NumPy的随机函数(3)

  • uniform(low,high,size): 产生具有均匀分布的数组,low起始值,high结束值,size形状
  • normal(loc,scale,size): 产生具有正态分布的数组,loc均值,scale标准差,size形状
  • poisson(lam,size): 产生具有泊松分布的数组,lam随机事件发生率,size形状
In [70]: n = np.random.normal(10,5,(3,4))

In [71]: n
Out[71]:
array([[ 16.41138338,   9.14097309,  12.8882903 ,   2.6251256 ],
       [ 10.39394227,  14.59206826,   7.5365132 ,  10.48231186],
       [  6.73620032,   8.89118781,   4.65856717,   3.86153973]])

# 将标准差变为1,得到的随机值就越靠近均值
In [72]: n = np.random.normal(10,1,(3,4))

In [73]: n
Out[73]:
array([[  8.20142698,   9.31479266,   8.59013113,  11.25239859],
       [ 10.46956276,  10.32692165,  11.80854321,   8.586932  ],
       [ 12.52330509,  10.3473178 ,   9.11264049,   8.94038275]])

4. Numpy的统计函数

4.1 Numpy的统计函数(1)

  • sum(a, axis=None):根据给定轴axis计算数组a相关元素之和,axis整数或元组
  • mean(a, axis=None):根据给定轴axis计算数组a相关元素的期望,axis整数或元组
  • average(a,axis=None,weights=None):根据给定轴axis计算数组a相关元素的加权平均值
  • std(a, axis=None):根据给定轴axis计算数组a相关元素的标准差
  • var(a, axis=None):根据给定轴axis计算数组a相关元素的方差

image

  • a[0][0][0-9] = 1,2,…9
  • a[0][1][0-9] = 10,11,…19
  • a[0][2][0-9] = 20,21,…29
  • a[0][3][0-9] = 30,31,…39
  • a[0][4][0-9] = 40,41,…49

  • a[1][0][0-9] = 50,51,…59
  • a[1][1][0-9] = 60,61,…69
  • a[1][2][0-9] = 70,71,…79
  • a[1][3][0-9] = 80,81,…89
  • a[1][4][0-9] = 90,91,…99

a[0-1][0-4][0-9]

  1. a是个三维数组,第1维为紧接[后的元素,第一维为2个元素,绿色框表示
  2. 第2维是紧接着第2个[的元素,第二维为5个元素,红色框表示
  3. 第3维是最内层的单个元素,如0,1…

对第2维内元素求和,a[0][0-4][0]求和,a[0][0-4][1]求和…等等,求和后第2维度就没有了,数组变成 a[0-1][0-9]。

4.2 Numpy的统计函数(1)-加权平均

通过mean函数,可以获取平均值,通过average()可以指定权值。

In [79]: a = np.arange(24).reshape(2,3,4)

In [80]: a
Out[80]:
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]]])

# 针对第1维的值取权值, 0×1 + 12×2 / 3 = 8
In [82]: np.average(a,axis=0,weights=[1,2])
Out[82]:
array([[  8.,   9.,  10.,  11.],
       [ 12.,  13.,  14.,  15.],
       [ 16.,  17.,  18.,  19.]])

# 针对第2维的值取权值, 0×1 + 4×2 + 8×3 / 6 = 5.33
In [83]: np.average(a,axis=1,weights=[1,2,3])
Out[83]:
array([[  5.33333333,   6.33333333,   7.33333333,   8.33333333],
       [ 17.33333333,  18.33333333,  19.33333333,  20.33333333]])

# 与上面的方式相同
In [84]: np.average(a,axis=2,weights=[1,2,3,4])
Out[84]:
array([[  2.,   6.,  10.],
       [ 14.,  18.,  22.]])

4.3 Numpy的统计函数(2)

  • min(a) max(a):计算数组a中元素的最小值、最大值
  • argmin(a) argmax(a):计算数组a中元素最小值、最大值的降一维后下标
  • unravel_index(index, shape):根据shape将一维下标index转换成多维下标
  • ptp(a):计算数组a中元素最大值与最小值的差
  • median(a):计算数组a中元素的中位数(中值)
In [87]: b = np.arange(15,0,-1).reshape(3,5)

In [88]: b
Out[88]:
array([[15, 14, 13, 12, 11],
       [10,  9,  8,  7,  6],
       [ 5,  4,  3,  2,  1]])

# 最大值为15
In [89]: np.max(b)
Out[89]: 15

# 最大值15作为的一维坐标为0
In [91]: np.argmax(b)
Out[91]: 0

In [92]: np.unravel_index(np.argmax(b),b.shape)
Out[92]: (0, 0)
# 差值
In [93]: np.ptp(b)
Out[93]: 14
# 中位数
In [94]: np.median(b)
Out[94]: 8.0

5. Numpy的梯度函数

np.gradient(f),计算数组f中元素的梯度,当f为多维时,返回每个维度梯度。 梯度:连续值之间的变化率,即斜率,XY坐标轴连续三个X坐标对应的Y轴值:a, b, c,其中,b的梯度是: (c‐a)/2。

In [96]: c = np.random.randint(0,50,(3,5))

In [97]: c
Out[97]:
array([[38, 22, 32,  2,  3],
       [31, 35, 27, 18, 13],
       [43, 48, 29, 45, 11]])

# 二维数组,所以有两个维度的梯度,首尾的梯度值, 31-38/1,43-38/2, 43-31/1
# 计算出来为 -7,2.5,12。
In [98]: np.gradient(c)
Out[98]:
[array([[ -7. ,  13. ,  -5. ,  16. ,  10. ],
        [  2.5,  13. ,  -1.5,  21.5,   4. ],
        [ 12. ,  13. ,   2. ,  27. ,  -2. ]]),
 array([[-16. ,  -3. , -10. , -14.5,   1. ],
        [  4. ,  -2. ,  -8.5,  -7. ,  -5. ],
        [  5. ,  -7. ,  -1.5,  -9. , -34. ]])]

梯度函数在声音和图像上应用较多,

6. 小结

  • CSV文件
    • np.loadtxt()
    • np.savetxt()
  • 多维数据存取
    • a.tofile()
    • np.fromfile()
    • np.save()
    • np.savez()
    • np.load()
  • 随机函数
    • np.random.rand()
    • np.random.randint()
    • np.random.shuffle()
    • np.random.choice()
    • np.random.randn()
    • np.random.seed()
    • np.random.permutation()
  • NumPy的统计函数
    • np.sum()
    • np.mean()
    • np.average()
    • np.std()
    • np.var()
    • np.median()
    • np.min()
    • np.max()
    • np.argmin()
    • np.argmax()
    • np.unravel_index()
    • np.ptp()
  • NumPy的梯度函数
    • np.grad ient()