《Python數(shù)據(jù)分析第二章》

本章涉及的主題如下:

  • 數(shù)據(jù)類型
  • 數(shù)組類型
  • 類型轉(zhuǎn)換
  • 創(chuàng)建數(shù)組
  • 索引
  • 花式索引
  • 切片
  • 處理數(shù)組的形狀
2.1NumPy數(shù)組對(duì)象

NumPy中的多為數(shù)組成為ndarray杰刽,它有兩個(gè)組成部分。

  • 數(shù)據(jù)本身
  • 描述數(shù)據(jù)的元數(shù)據(jù)
    在數(shù)組的處理過程中涝婉,原始信息不受影響墩弯,變化的只是元數(shù)據(jù)而已渔工。
    在第一章中引矩,我們?cè)?jīng)用arange()函數(shù)來生成數(shù)組旺韭。實(shí)際上区端,那是用來存放一組數(shù)值的一維數(shù)組织盼,這里的nadarray則可以具有一個(gè)以上的維度沥邻。

NumPy數(shù)組的優(yōu)勢(shì)
NumPy數(shù)組通常是由相同種類的元素組成的唐全,即數(shù)組中的數(shù)據(jù)項(xiàng)的類型必須一致芦瘾。NumPy數(shù)組元素類型一致的好處是:由于知道數(shù)組元素的類型相同近弟,所以能輕松確定存儲(chǔ)數(shù)組所需空間的大小祷愉。同時(shí)二鳄,NumPy數(shù)組還能夠運(yùn)用向量化運(yùn)算來處理整個(gè)數(shù)組髓窜;而完成同樣的任務(wù)寄纵,Python的列表則通常必須借助循環(huán)語句便利列表程拭,并對(duì)逐個(gè)元素進(jìn)行相應(yīng)的處理恃鞋。此外恤浪,NumPy使用了優(yōu)化過的CAPI资锰,所以運(yùn)算速度格外快绷杜。

NumPy數(shù)組的索引方法和Python類似鞭盟,下標(biāo)從0開始齿诉。

我們來創(chuàng)建一個(gè)數(shù)組試一下,查看它的數(shù)據(jù)類型和形狀

import numpy as np
a = np.arange(5)
print(a.dtype)
print(a)
print(a.shape)

輸出結(jié)果為:

int32
[0 1 2 3 4]
(5,)

因?yàn)槲业腜ython是32位版本抵恋,所以得到的結(jié)果是int32弧关;如你所見世囊,該向量有5個(gè)元素株憾,它們的值分別是0到4嗤瞎。該數(shù)組的shape屬性是一個(gè)元組猫胁,這是一個(gè)單元素?cái)?shù)組弃秆,所以存放的是每一個(gè)數(shù)組在每一個(gè)維度的長度菠赚。

2.2創(chuàng)建多維數(shù)組
import numpy as np
from numpy import  array
m = array([np.arange(2), np.arange(2)])
print(m)
print(m.shape)

運(yùn)行結(jié)果:

[[0 1]
 [0 1]]
(2, 2)

注意這里需要從numpy中Import array包衡查。
在這里拌牲,我們直接用np.arrange()創(chuàng)建了2 X 2的數(shù)組拍埠,利用array()函數(shù)創(chuàng)建數(shù)組時(shí)枣购,需要傳遞給它一個(gè)對(duì)象棉圈,而且這個(gè)對(duì)象必須是數(shù)組類型的分瘾,如Python列表。

2.3選擇NumPy數(shù)組元素
import numpy as np
from numpy import  array
a = array([[1,2], [3,4]])
print(a)
print(a[0, 0])
print(a[0, 1])
print(a[1, 0])
print(a[1, 1])

運(yùn)行結(jié)果:

[[1 2]
 [3 4]]
1
2
3
4

上面的矩陣是通過向array()函數(shù)傳遞一個(gè)由列表組成的列表得到的氏捞,然后通過逐個(gè)選擇矩陣的各個(gè)元素液茎,記住下標(biāo)是從0開始的捆等。
選擇數(shù)組是一件非常簡(jiǎn)單的事,對(duì)于數(shù)組a明郭,只要通過a[m, n]的形式薯定,就能訪問數(shù)組內(nèi)的元素话侄,其中m和n分別為數(shù)組元素的下標(biāo)吞杭。

2.4NumPy的數(shù)值類型

Python自身雖然支持整型篇亭、浮點(diǎn)型和復(fù)數(shù)型,但是對(duì)于科學(xué)計(jì)算來說谊却,還遠(yuǎn)遠(yuǎn)不夠,我們需要更多的數(shù)據(jù)類型碴萧,來滿足精度和存儲(chǔ)大小方面的各種不同要求破喻。為此曹质,NumPy提供了更加豐富的數(shù)據(jù)類型。而每一種數(shù)據(jù)類型都具有相應(yīng)的轉(zhuǎn)換函數(shù):

print(float(42))
print(int(42.0))
print(bool(42))
print(bool(0))
print(float(True))
print(float(False))

運(yùn)行結(jié)果:

42.0
42
True
False
1.0
0.0

許多函數(shù)都帶有一個(gè)制定數(shù)據(jù)類型的參數(shù)宅静,這個(gè)參數(shù)通常是可選的:

import numpy as np
from numpy import array
np.arange(7, dtype = np.uint16)

輸出結(jié)果:

array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)

注意纤垂,這里的dtype類型中的數(shù)據(jù)類型也要指定偉np.uint洒忧。
謹(jǐn)記:不允許把復(fù)數(shù)類型轉(zhuǎn)化為整型熙侍。同樣,也不允許把復(fù)數(shù)轉(zhuǎn)化為浮點(diǎn)數(shù)巷送,此外笑跛,復(fù)數(shù)的分量j是其虛部的系數(shù),允許把浮點(diǎn)數(shù)轉(zhuǎn)化為復(fù)數(shù)陈哑,如complex(1, 0)是合法的惊窖,復(fù)數(shù)的實(shí)部和虛部分別使用real()函數(shù)和imag()函數(shù)提取界酒。

2.4.1數(shù)據(jù)類型對(duì)象

數(shù)據(jù)類型對(duì)象是numpy.dtype類的實(shí)例。數(shù)組是一種數(shù)據(jù)類型署辉。嚴(yán)格來講哭尝,NumPy數(shù)組中的每個(gè)元素都要具有相同的數(shù)據(jù)類型剖煌。數(shù)據(jù)類型表明了數(shù)據(jù)占用的字節(jié)數(shù)材鹦,所以占用字節(jié)的具體數(shù)目一般存放在類dtype的itemsize屬性中逝淹。

a.dtype.itemsize

輸出結(jié)果:

4
2.4.2字符碼

啥是字符碼,我的理解就是用一個(gè)代碼表示數(shù)據(jù)類型桶唐,這樣可以簡(jiǎn)化程序栅葡,比如:

import numpy as np
from numpy import array
a = np.arange(7, dtype = 'f')
b = np.arange(7, dtype = "D")
print(a, b)

輸出結(jié)果:

[0. 1. 2. 3. 4. 5. 6.] [0.+0.j 1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j 6.+0.j]
2.4.3Dtype構(gòu)造函數(shù)

創(chuàng)建數(shù)據(jù)類型時(shí),手段有很多欣簇。

  • 可以使用Python自帶的常規(guī)浮點(diǎn)數(shù)型
  • 可以使用字符碼規(guī)定單精度浮點(diǎn)數(shù)
  • 可以用字符碼定義雙精度浮點(diǎn)數(shù)
  • 可以向dtype構(gòu)造函數(shù)傳遞一個(gè)雙字符碼。其中坯约,第一個(gè)字符表示數(shù)據(jù)類型熊咽,第二個(gè)字符是一個(gè)數(shù)字,表示該類型占用的字節(jié)數(shù)闹丐。
import numpy as np
from numpy import array
print(np.dtype(np.float))
print(np.dtype('f'))
print(np.dtype('d'))
print(np.dtype('f8'))

輸出結(jié)果:

float64
float32
float64
float64
2.4.4dtype屬性
import numpy as np
t = np.dtype('Float64')
print(t.char)
print(t.type)
print(t.str)

輸出結(jié)果:

d
<class 'numpy.float64'>
<f8

其第一行返回其字符碼横殴;第二行返回其類型屬性;第三行中dtype的屬性str中保存的是一個(gè)表示數(shù)據(jù)類型的字符串卿拴,其中第一個(gè)字符描述的是數(shù)據(jù)類型衫仑,如果需要,后面會(huì)跟著字符碼和數(shù)組堕花,用來存儲(chǔ)每個(gè)數(shù)組元素所需的字節(jié)數(shù)惑畴。

2.5一維數(shù)組的切片和索引

一維NumPy數(shù)組的切片操作與Python列表的切片一樣。

import numpy as np
from numpy import array
a = np.arange(9)
print(a[3 : 7])    #指定下標(biāo)選擇數(shù)組的部分元素
print(a[:7 :2])    #制定下標(biāo)選擇元素航徙,并設(shè)定下標(biāo)每次遞增2  
print(a[::-1])    #用負(fù)值下標(biāo)翻轉(zhuǎn)數(shù)組

輸出結(jié)果:

[3 4 5 6]
[0 2 4 6]
[8 7 6 5 4 3 2 1 0]
2.6處理數(shù)組形狀

前面,我們學(xué)習(xí)過reshape()函數(shù)陷虎,實(shí)際上到踏,除了數(shù)組形狀的調(diào)整外,數(shù)組的擴(kuò)充也是一個(gè)經(jīng)常碰到的乏味工作尚猿。

import numpy as np
b = np.arange(24).reshape(2, 3, 4)
print(b,"\n")
c = b.ravel()
print(c,"\n")
d = b.flatten()
print(d,"\n")
b.shape = (6, 4)
print(b,"\n")
e = b.transpose()
print(e,"\n")
b.resize((2, 12))
print(b,"\n")

輸出結(jié)果:

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

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]] 

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]] 

[[ 0  4  8 12 16 20]
 [ 1  5  9 13 17 21]
 [ 2  6 10 14 18 22]
 [ 3  7 11 15 19 23]] 

[[ 0  1  2  3  4  5  6  7  8  9 10 11]
 [12 13 14 15 16 17 18 19 20 21 22 23]] 

這里有一個(gè)細(xì)節(jié)問題:

  • reshape:有返回值窝稿,所謂有返回值,即不對(duì)原始多維數(shù)組進(jìn)行修改凿掂;
  • resize:無返回值伴榔,所謂有返回值,即會(huì)對(duì)原始多維數(shù)組進(jìn)行修改庄萎;

即這里resize()函數(shù)會(huì)直接修改原數(shù)組踪少,而不是輸出新的數(shù)值!

代碼中的函數(shù)都是處理對(duì)數(shù)組的形狀進(jìn)行處理:

  • 拆解:ravel()函數(shù)將多維數(shù)組變成一維數(shù)組糠涛。
  • 拉直:Flatten()函數(shù)功能與ravel()相同援奢,但是flatten()返回的是真實(shí)的數(shù)組,需要分配新的內(nèi)存空間忍捡;而ravel()函數(shù)返回的只是數(shù)組的視圖集漾。
  • 用元組指定數(shù)組形狀:除了reshape()函數(shù)外切黔,還可以用元組來輕松定義數(shù)組的形狀
  • 轉(zhuǎn)置:在線性代數(shù)中,矩陣的轉(zhuǎn)置操作非常常見具篇。轉(zhuǎn)置是一種數(shù)據(jù)變換方法纬霞,對(duì)于二維表而言,轉(zhuǎn)置就意味著行變成列驱显,列變成行诗芜。
  • 調(diào)整大小,作用類似于reshape()秒紧,但是會(huì)改變所作用的數(shù)組绢陌。
2.6.1堆疊數(shù)組

從深度看,數(shù)組既可以橫向疊放熔恢,也可以豎向疊放脐湾。為此,可以使用vstack()叙淌、dstack()秤掌、hstack()、column_stack()鹰霍、row_stack()和concatenate()等函數(shù)闻鉴。

import numpy as np
a = np.arange(9).reshape(3, 3)
print(a,"\n")
b = 2 * a 
print(b,"\n")
c = np.hstack((a, b))    #水平疊加
print(c,"\n")
d = np.concatenate((a, b), axis = 1)    #用concatenate()函數(shù)參數(shù)axis = 1實(shí)現(xiàn)水平疊加效果
print(d,"\n")
e = np.vstack((a, b))    #垂直疊加
print(e,"\n")
f = np.concatenate((a, b), axis = 0)    #用concatenate()函數(shù)參數(shù)axis = 0實(shí)現(xiàn)垂直疊加效果
print(f,"\n")
g = np.dstack((a, b))    #深度疊加
print(g, "\n")

oned = np.arange(2)   
print(oned, "\n")
twice_oned = 2 * oned
print(twice_oned, "\n")
h = np.column_stack((oned, twice_oned))     #列式疊加
print(h, "\n")
i = np.column_stack((a, b))    #這種列式疊加有點(diǎn)類似于hstack水平疊加
print(i, "\n")

print(i == c,"\n")

j = np.row_stack((oned, twice_oned))    #行式疊加
print(j,"\n")
k = np.row_stack((a, b))    #這種列式疊加有點(diǎn)類似于vstack垂直疊加
print(k,"\n")

print(e == k,"\n")

輸出結(jié)果:

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

[[ 0  2  4]
 [ 6  8 10]
 [12 14 16]] 

[[ 0  1  2  0  2  4]
 [ 3  4  5  6  8 10]
 [ 6  7  8 12 14 16]] 

[[ 0  1  2  0  2  4]
 [ 3  4  5  6  8 10]
 [ 6  7  8 12 14 16]] 

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 0  2  4]
 [ 6  8 10]
 [12 14 16]] 

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 0  2  4]
 [ 6  8 10]
 [12 14 16]] 

[[[ 0  0]
  [ 1  2]
  [ 2  4]]

 [[ 3  6]
  [ 4  8]
  [ 5 10]]

 [[ 6 12]
  [ 7 14]
  [ 8 16]]] 

[0 1] 

[0 2] 

[[0 0]
 [1 2]] 

[[ 0  1  2  0  2  4]
 [ 3  4  5  6  8 10]
 [ 6  7  8 12 14 16]] 

[[ True  True  True  True  True  True]
 [ True  True  True  True  True  True]
 [ True  True  True  True  True  True]] 

[[0 1]
 [0 2]] 

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 0  2  4]
 [ 6  8 10]
 [12 14 16]] 

[[ True  True  True]
 [ True  True  True]
 [ True  True  True]
 [ True  True  True]
 [ True  True  True]
 [ True  True  True]] 

這里有一個(gè)細(xì)節(jié)問題:
堆疊函數(shù)的參數(shù)是一個(gè)元組的時(shí)候,要轉(zhuǎn)換兩個(gè)數(shù)組為一個(gè)元組茂洒,即用兩個(gè)括號(hào)將兩個(gè)數(shù)組括起來組成一個(gè)元組孟岛。

堆放數(shù)組的方法總結(jié)如下:

  • 水平疊加
  • 垂直疊加
  • 深度疊加:這種方法是沿著第三個(gè)坐標(biāo)軸(縱向)的方向疊加一摞數(shù)組,可以在一個(gè)圖像數(shù)據(jù)的二維數(shù)組上疊加另一幅圖像的數(shù)據(jù)督勺。
  • 列式堆疊
  • 行式堆疊
2.6.2拆分NumPy數(shù)組

可以從縱向渠羞、橫向和深度方向來拆分?jǐn)?shù)組,相關(guān)函數(shù)有hsolit()智哀、vsplit()次询、dsplit()和split()。我們既可以把數(shù)組分成相同形狀的數(shù)組瓷叫,也可以從規(guī)定的位置開始切取數(shù)組屯吊。

import numpy as np
a = np.arange(9).reshape(3, 3)
print(a,"\n")
b = np.hsplit(a, 3)    #橫向拆分
print(b,"\n")    
c = np.split(a, 3, axis = 1)    #相當(dāng)于調(diào)用參數(shù)axis = 1的split()函數(shù)
print(c,"\n")
d = np.vsplit(a, 3)     #縱向拆分
print(d,"\n")
e = np.split(a, 3, axis = 0)     #相當(dāng)于調(diào)用參數(shù)axis = 0的split()函數(shù)
print(e,"\n")
f = np.arange(27).reshape(3, 3, 3)    
print(f,"\n")
g = np.dsplit(f, 3)    #沿著深度方向分解數(shù)組,本例秩為3
print(g,"\n")

輸出結(jié)果:

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

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

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

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

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

[[[ 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]]] 

[array([[[ 0],
        [ 3],
        [ 6]],

       [[ 9],
        [12],
        [15]],

       [[18],
        [21],
        [24]]]), array([[[ 1],
        [ 4],
        [ 7]],

       [[10],
        [13],
        [16]],

       [[19],
        [22],
        [25]]]), array([[[ 2],
        [ 5],
        [ 8]],

       [[11],
        [14],
        [17]],

       [[20],
        [23],
        [26]]])] 
2.6.3NumPy數(shù)組的屬性

除shape和dtype屬性外摹菠,ndarray類型的屬性還很多:

  • ndim屬性存儲(chǔ)的是維度的數(shù)量
  • size屬性用來保存元素的數(shù)量
  • itemsize屬性可以返回?cái)?shù)組中各個(gè)元素所占用的字節(jié)數(shù)
  • 如果想知道存儲(chǔ)整個(gè)數(shù)組所需的字節(jié)數(shù)量盒卸,可以求助于nbytes屬性,這個(gè)屬性值正好是itemsize屬性值和size屬性值之積次氨。
    -T屬性的作用與transpose()函數(shù)相同
  • 如果數(shù)組的秩(rank)小于2世落,那么所得只是一個(gè)數(shù)組的視圖:這里其實(shí)有個(gè)小問題,我認(rèn)為這個(gè)矩陣的秩為1,但是輸出確是2屉佳,所以這里也體現(xiàn)不了得到視圖的效果(因?yàn)橹葹?嘛)谷朝。比如:
a = np.array([[1, 2, 3, 4],
    [2, 4, 6, 8]])
print(a.ndim)

輸出結(jié)果為2,這里我覺得這很明顯是秩為1的矩陣拔浠ā圆凰!

  • 對(duì)于NumPy來說,復(fù)數(shù)用j表示
  • real屬性將返回?cái)?shù)組的實(shí)部体箕,當(dāng)數(shù)組元素全為實(shí)數(shù)時(shí)专钉,就返回?cái)?shù)組本身
  • imag屬性存放的是數(shù)組的虛部
  • 如果數(shù)組含有復(fù)數(shù),那么它的數(shù)據(jù)類型將自動(dòng)變?yōu)閺?fù)數(shù)類型
  • flat屬性可返回一個(gè)numpy.flatiter對(duì)象累铅,這是獲得flatiter對(duì)象的唯一方法跃须,但我們無法訪問flatiter的構(gòu)造函數(shù)⊥奘蓿可以通過flat[1, 3]獲取對(duì)象中的元素菇民,此外還可以給flat屬性賦值,不過需要注意的是投储,這個(gè)值將會(huì)覆蓋整個(gè)數(shù)組內(nèi)的所有元素的值第练。
import numpy as np
from numpy import array
a = np.arange(24).reshape(2, 12)
print(a,"\n")
print(a.ndim,"\n")    #求其維度的數(shù)量
print(a.size,"\n")    #求其保存元素的數(shù)量
print(a.itemsize,"\n")    #返回?cái)?shù)組中各個(gè)元素所占用的字節(jié)數(shù)
print(a.nbytes,"\n")    #整個(gè)數(shù)組所需的字節(jié)數(shù)量
print(a.size * a.itemsize,"\n")
a.resize(6, 4)
print(a,"\n")
print(a.T,"\n")    #轉(zhuǎn)置
print(a.ndim,"\n")    #這里矩陣的秩為什么是2!B贶瘛=刻汀!Q小Sの唷!?吞!V就骸!
a = np.array([1.j + 1, 2.j + 3])
print(a,"\n")
print(a.real,"\n")    #返回?cái)?shù)組的實(shí)部
print(a.imag,"\n")    #返回?cái)?shù)組的虛部
print(a.dtype,"\n")    #返回復(fù)數(shù)的數(shù)據(jù)類型
print(a.dtype.str,"\n")
a = np.arange(4).reshape(2,2)
print(a,"\n")
b = a.flat    #flat函數(shù)就像迭代器一樣讀取每個(gè)數(shù)組
print(b,"\n")
for it in b:
    print(it,"\n")
print(a.flat[2],"\n")
print(a.flat[[1, 3]],"\n")
print(a,"\n")
a.flat[[1, 3]] = 7
print(a,"\n")
a.flat = 7
print(a,'\n')

輸出結(jié)果:

[[ 0  1  2  3  4  5  6  7  8  9 10 11]
 [12 13 14 15 16 17 18 19 20 21 22 23]] 

2 

24 

4 

96 

96 

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]] 

[[ 0  4  8 12 16 20]
 [ 1  5  9 13 17 21]
 [ 2  6 10 14 18 22]
 [ 3  7 11 15 19 23]] 

2 

[1.+1.j 3.+2.j] 

[1. 3.] 

[1. 2.] 

complex128 

<c16 

[[0 1]
 [2 3]] 

<numpy.flatiter object at 0x04AEAB70> 

0 

1 

2 

3 

2 

[1 3] 

[[0 1]
 [2 3]] 

[[0 7]
 [2 7]] 

[[7 7]
 [7 7]] 
2.6.4數(shù)組的轉(zhuǎn)換

可以把NumPy數(shù)組轉(zhuǎn)換成Python列表嚼酝,使用tolist()函數(shù)。

  • 轉(zhuǎn)換成列表
  • astype()函數(shù)可以把數(shù)組元素轉(zhuǎn)換成制定類型
    提示:當(dāng)complex類型轉(zhuǎn)換成int類型時(shí)竟坛,虛部將被丟棄闽巩,此外,還需要將數(shù)據(jù)類型的名稱以字符串的形式傳遞給astype()函數(shù)担汤。
import numpy as np
from numpy import array
a = np.array([1 + 1.j, 3 + 2.j])
b = a.astype(int)
print(b)
c = a.tolist()
print(c)
d = b.astype('complex')
print(d)

輸出結(jié)果:

[1 3]
[(1+1j), (3+2j)]
[1.+0.j 3.+0.j]
D:\Python\lib\site-packages\ipykernel_launcher.py:4: ComplexWarning: Casting complex values to real discards the imaginary part
  after removing the cwd from sys.path.
2.7創(chuàng)建數(shù)組的視圖和拷貝

在NumPy的師姐中涎跨,視圖不是只讀的,因?yàn)槟悴豢赡苁刂A(chǔ)數(shù)據(jù)一動(dòng)不動(dòng)崭歧,關(guān)鍵在于要知道隅很,當(dāng)前處理的是共享的數(shù)組視圖,還是數(shù)組數(shù)據(jù)的副本率碾。舉例來說叔营,可以使用數(shù)組的一部分生成視圖屋彪。這意味著,如果先將數(shù)組的某部分賦予給一個(gè)變量绒尊,然后修改原數(shù)組中相應(yīng)位置的數(shù)據(jù)畜挥,那么這個(gè)變量的值也會(huì)隨之變化。我們可以根據(jù)著名的萊娜照片創(chuàng)建數(shù)組婴谱,然后創(chuàng)建視圖蟹但,隨后修改它。
因?yàn)槿R娜圖片已經(jīng)被scipy移除谭羔,這里用替換文件ascent代替:

import scipy.misc    #從scipy中獲取圖像數(shù)組
import matplotlib.pyplot as plt    #獲取畫圖matplotlib庫用于繪圖和顯示

ascent = scipy.misc.ascent()    #獲取
acopy = ascent.copy()
aview = ascent.view()
plt.subplot(221)
plt.imshow(ascent)
plt.subplot(222)
plt.imshow(acopy)
plt.subplot(223)
plt.imshow(aview)
aview.flat = 0
plt.subplot(224)
plt.imshow(aview)
plt.show()

輸出結(jié)果:

哈哈這里反而產(chǎn)生了一個(gè)相悖的結(jié)論华糖,這里在程序結(jié)束部分修改視圖,同時(shí)改變了原來的圖片數(shù)組瘟裸,導(dǎo)致134圖都應(yīng)該變紫客叉,表明除了復(fù)制的數(shù)組,其他數(shù)組都被程序結(jié)尾的改變而改變景描,證明:視圖不是只讀的十办。但是這里原圖和視圖都沒變!3住向族!

2.8花式索引

花式索引是一種傳統(tǒng)的索引方法,它不使用整數(shù)或切片棠绘。這里我們利用花式索引將樓梯照片對(duì)角線上的值全部置0件相,相當(dāng)于沿著兩條交叉的對(duì)象線畫兩條黑線。

import scipy.misc   
import matplotlib.pyplot as plt    

ascent = scipy.misc.ascent()  
xmax = ascent.shape[0]    
ymax = ascent.shape[1]    
ascent[range(xmax), range(ymax)] = 0    #給x和y值規(guī)定兩個(gè)不同的范圍
ascent[range(xmax-1, -1, -1), range(ymax)] = 0    #規(guī)定兩個(gè)不同的取值范圍氧苍,但是規(guī)則不變
plt.imshow(ascent)
plt.show()

輸出結(jié)果:

我們給x和y規(guī)定了兩個(gè)不同的取值范圍夜矗,這些范圍來索引圖片∪门埃花式索引是在一個(gè)內(nèi)部的NumPy迭代器對(duì)象的基礎(chǔ)上實(shí)現(xiàn)的紊撕,分3步完成。
(1)創(chuàng)建迭代器對(duì)象
(2)將迭代器對(duì)象綁定到數(shù)組
(3)經(jīng)由迭代器訪問數(shù)組元素赡突,利用位置列表進(jìn)行索引对扶。

我的解釋:把圖片轉(zhuǎn)換為數(shù)組后,定義max(512:黑色)惭缰,然后利用range()函數(shù)將對(duì)角線設(shè)置為黑色浪南。

2.9基于位置列表的索引方法
import scipy.misc   
import matplotlib.pyplot as plt   
import numpy as np

ascent = scipy.misc.ascent()  
xmax = ascent.shape[0]    
ymax = ascent.shape[1] 

def shuffle_indices(size):
    arr = np.arange(size)
    np.random.shuffle(arr)    #shuffle()函數(shù)將數(shù)組中的元素按隨機(jī)的索引號(hào)重新排列
    
    return arr

xindices = shuffle_indices(xmax)
np.testing.assert_equal(len(xindices), xmax)
yindices = shuffle_indices(ymax)
np.testing.assert_equal(len(yindices), ymax)
plt.imshow(ascent[np.ix_(xindices, yindices)])    #畫出打亂后的索引
plt.show()

運(yùn)行結(jié)果:

這里解釋兩個(gè)函數(shù):

  • shuffle函數(shù):
import random

list = [20, 16, 10, 5];
random.shuffle(list)
print(list)
random.shuffle(list)
print(list)

運(yùn)行結(jié)果:

[20, 16, 5, 10]
[10, 5, 16, 20]
  • ix_()函數(shù)
    這個(gè)函數(shù)可以根據(jù)多個(gè)序列生成一個(gè)網(wǎng)格,他需要一個(gè)一維序列作為參數(shù)漱受,并返回一個(gè)由NumPy數(shù)組構(gòu)成的元組络凿。
import numpy as np
np.ix_([0, 1], [2, 3])

運(yùn)行結(jié)果:

(array([[0],
        [1]]), array([[2, 3]]))
2.10用布爾型變量索引NumPy數(shù)組

布爾型索引是根據(jù)布爾型數(shù)組來索引元素的方法,屬于花式索引系列。

import scipy.misc   
import matplotlib.pyplot as plt   
import numpy as np

ascent = scipy.misc.ascent() 

def get_indices(size):
    arr = np.arange(size)
    return arr % 4 == 0

ascent = ascent.copy()
xindices = get_indices(ascent.shape[0])
yindices = get_indices(ascent.shape[1])
ascent[xindices, yindices] = 0
plt.subplot(211)
plt.imshow(ascent)
ascent2 = ascent.copy()
ascent2[((ascent > ascent.max()/4) & (ascent < 3 * ascent.max()/4))] = 0
plt.subplot(212)
plt.imshow(ascent2)
plt.show()

運(yùn)行結(jié)果:

1.定義函數(shù)絮记,在對(duì)角線上畫點(diǎn)摔踱,選擇的是照片對(duì)角線上可以被4整除的那些位置上的點(diǎn),然后僅繪出選定的那些點(diǎn)到千。
2.根據(jù)元素值的情況置0昌渤。選擇數(shù)組值結(jié)余最大值的1/4到3/4的那些元素將其置0.

這里有個(gè)小問題就是書中源代碼是會(huì)報(bào)錯(cuò)的,報(bào)錯(cuò)信息如下:

TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

這是因?yàn)榈?8行的運(yùn)算優(yōu)先級(jí)問題憔四,在上述兩種情況下都加上()就沒問題了膀息。

2.11NumPy數(shù)組的廣播

當(dāng)操作對(duì)象的形狀不一樣時(shí),NumPy會(huì)盡力進(jìn)行處理了赵。
例如潜支,假設(shè)一個(gè)數(shù)組要跟一個(gè)標(biāo)量想乘,這時(shí)標(biāo)量需要根據(jù)數(shù)組的形狀進(jìn)行擴(kuò)展柿汛,然后才可以執(zhí)行乘法運(yùn)算冗酿,這個(gè)擴(kuò)展過程叫做廣播

import scipy.io.wavfile
import matplotlib.pyplot as plot
import urllib.request
import numpy as np
response = urllib.request.urlopen('http://www.thesoundarchive.com/austinpowers/smashingbaby.wav')
print(response.info)
WAV_FILE = 'smashingbaby.wav'
filehandle = open(WAV_FILE, 'wb+')
filehandle.write(response.read())
filehandle.close()
sample_rate, data = scipy.io.wavfile.read(WAV_FILE)
print("Data type", data.dtype, "Shape", data.shape)
plt.subplot(2, 1, 1)
plt.title("Original")
plt.plot(data)
newdata = data * 0.2
newdata = newdata.astype(np.uint8)
print("Data type", newdata.dtype, "shape", newdata.shape)
scipy.io.wavfile.write("quiet.wav",
                      sample_rate, newdata)
plt.subplot(2, 1, 2)
plt.title("Quiet")
plt.plot(newdata)
plt.show()

輸出結(jié)果:

<bound method HTTPResponse.info of <http.client.HTTPResponse object at 0x0E290D10>>
Data type uint8 Shape (43584,)
Data type uint8 shape (43584,)

這個(gè)程序下載一個(gè)音頻文件络断,然后以此為基礎(chǔ)裁替,生成一個(gè)新的靜音版本。
1.讀取WAV文件
哈哈這里幸虧已經(jīng)看了爬蟲貌笨,也說明了數(shù)據(jù)獲取的重要性弱判,雖然這一章應(yīng)該focus在數(shù)據(jù)處理上,書中的代碼應(yīng)該修改urrlib2偉urrlib2.request锥惋,這是python3區(qū)別之前的地方之一昌腰,此外,書中的代碼對(duì)于寫入音頻文件如果用w模式會(huì)報(bào)錯(cuò):

TypeError: write() argument must be str, not bytes

這是因?yàn)椋?/p>

可能又是版本變化問題吧膀跌!這里通過爬蟲的形式從電影《王牌大間諜》中下載狂嚎式的歌曲遭商,Scipy中有一個(gè)wavfile子程序包,用來加載音頻數(shù)據(jù)捅伤,或者生成WAV格式的文件劫流。可以使用read()函數(shù)直接讀取文件丛忆,它返回一個(gè)數(shù)據(jù)陣列及采樣率祠汇。
2.回執(zhí)WAV原始數(shù)據(jù)
3.新建一個(gè)數(shù)組
現(xiàn)在,用NumPy生成一段寂靜的聲音蘸际,實(shí)際上就是將原數(shù)組乘以一個(gè)常數(shù),從而得到一個(gè)新數(shù)組徒扶,因?yàn)檫@個(gè)新數(shù)組的元素值肯定是變小了粮彤,這就是廣播術(shù)的用武之地。最后,我們要確保新數(shù)組和原數(shù)組的類型一致导坟。即WAV格式屿良。
4.寫入一個(gè)WAV文件中
5.繪制出新的WAV數(shù)據(jù)
6.展示原始的WAV文件中的數(shù)值圖像,以及數(shù)值變小后的新數(shù)組的圖像惫周。

可以聽一下效果尘惧!哈哈真的消音了。

2.12小結(jié)

本章递递,學(xué)習(xí)了NumPy的基礎(chǔ)知識(shí):數(shù)據(jù)類型和數(shù)組喷橙。數(shù)組有很多屬性,這些屬性都是用來描述該數(shù)組的特性的登舞。
與Python標(biāo)準(zhǔn)的列表相比贰逾,NumPy數(shù)組使用的切片和索引方法更加高效,此外菠秒,NumPy數(shù)組還能夠?qū)Χ嗑S數(shù)組進(jìn)行處理疙剑。
我們可以用各種方式改變數(shù)組的形狀,如堆疊践叠、重定尺寸言缤、重塑形狀以及拆分等。
有了這些基礎(chǔ)知識(shí)后禁灼,從第三章開始管挟,就要學(xué)習(xí)如何通過常見的函數(shù)來分析數(shù)據(jù)了,這將涉及主要統(tǒng)計(jì)函數(shù)和數(shù)值函數(shù)的用法匾二。

咳咳

數(shù)組學(xué)了很多遍哮独,但是這次應(yīng)該是比較系統(tǒng)的整理了一遍,Python這個(gè)語法就是很多察藐,知道怎么用但是真的實(shí)際用就笨手笨腳皮璧,還是不能熟能生巧!
這一章中對(duì)圖片和音頻的數(shù)據(jù)處理實(shí)例說明數(shù)據(jù)處理不是簡(jiǎn)簡(jiǎn)單單的處理數(shù)據(jù)分飞,數(shù)據(jù)類型非常多悴务,通過數(shù)據(jù)轉(zhuǎn)換,可以將現(xiàn)實(shí)世界中的很多問題轉(zhuǎn)換為數(shù)學(xué)運(yùn)算的方式解決譬猫。
線性代數(shù)補(bǔ)考才過讯檐,現(xiàn)在重新需要用到了,還有點(diǎn)慌染服,哈哈别洪,秩都不會(huì)算了!
記錄可以讓我不囫圇吞棗式的看書柳刮,邊看邊記錄可能也會(huì)記的更深一點(diǎn)吧哈哈挖垛!真的喜歡簡(jiǎn)書的這種書寫方式痒钝,

?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痢毒,隨后出現(xiàn)的幾起案子送矩,更是在濱河造成了極大的恐慌,老刑警劉巖哪替,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栋荸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凭舶,警方通過查閱死者的電腦和手機(jī)晌块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來库快,“玉大人摸袁,你說我怎么就攤上這事∫迤粒” “怎么了靠汁?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闽铐。 經(jīng)常有香客問我蝶怔,道長,這世上最難降的妖魔是什么兄墅? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任踢星,我火速辦了婚禮,結(jié)果婚禮上隙咸,老公的妹妹穿的比我還像新娘沐悦。我一直安慰自己,他們只是感情好五督,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布藏否。 她就那樣靜靜地躺著,像睡著了一般充包。 火紅的嫁衣襯著肌膚如雪副签。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天基矮,我揣著相機(jī)與錄音淆储,去河邊找鬼。 笑死家浇,一個(gè)胖子當(dāng)著我的面吹牛本砰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钢悲,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼点额,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼青团!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咖楣,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芦昔,沒想到半個(gè)月后诱贿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咕缎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年珠十,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凭豪。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焙蹭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嫂伞,到底是詐尸還是另有隱情孔厉,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布帖努,位于F島的核電站撰豺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拼余。R本人自食惡果不足惜污桦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匙监。 院中可真熱鬧凡橱,春花似錦、人聲如沸亭姥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽致份。三九已至变抽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間氮块,已是汗流浹背绍载。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工汁展, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留静浴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓腰奋,卻偏偏與公主長得像蝠引,于是被迫代替她去往敵國和親阳谍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛀柴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容