0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Numpy居然有這么多陷阱?

馬哥Linux運(yùn)維 ? 來源:lq ? 2018-12-03 16:37 ? 次閱讀

陷阱一:數(shù)據(jù)結(jié)構(gòu)混亂

array 和 matrix 都可以用來表示多維矩陣:

看起來效果不錯(cuò)。假設(shè)我們要對(duì)數(shù)據(jù)進(jìn)行篩選,取第 1 列的第 1 行和第 3 行數(shù)據(jù)構(gòu)成一個(gè) 2 x 1 的列向量。先看對(duì) array 的做法:

從 Out[101] 可以看到一個(gè)陷阱,a[:, 0] 過濾完應(yīng)該是一個(gè) 3 x 1 的列向量,可是它變成了行向量。其實(shí)也不是真正意義上的行向量,因?yàn)樾邢蛄?shape 應(yīng)該是 3 x 1,可是他的 shape 是 (3,) ,這其實(shí)已經(jīng)退化為一個(gè)數(shù)組了。所以,導(dǎo)致最后 In [110] 出錯(cuò)。只有像 In [111] 那樣 reshape 一下才可以。我不知道大家暈了沒有,我是已經(jīng)快暈了。

相比之下,matrix 可以確保運(yùn)算結(jié)果全部是二維的,結(jié)果相對(duì)好一點(diǎn)。為什么只是相對(duì)好一點(diǎn)呢?呆會(huì)兒我們?cè)賮硗峦?matrix 的槽點(diǎn)。

看起來還不錯(cuò)。不過槽點(diǎn)就來了。Out [114] 我們預(yù)期的輸入結(jié)果應(yīng)該是一個(gè) 2 x 1 的列向量,可是這里變成了 1 x 2 的行向量!

為什么我會(huì)在意行向量和列向量?在矩陣運(yùn)算里,行向量和列向量是不同的。比如一個(gè) m x 3 的矩陣可以和 3 x 1 的列向量叉乘,結(jié)果是 m x 1 的列向量。而如果一個(gè) m x 3 的矩陣和 1 x 3 的行向量叉乘是會(huì)報(bào)錯(cuò)的。

陷阱二:數(shù)據(jù)處理能力不足,語言效率低

我們?cè)倏磦€(gè)例子。假設(shè) X 是 5 x 2 的矩陣,Y 是 5 X 1 的 bool 矩陣,我們想用 Y 來過濾 X ,即取出 Y 值為 True 的項(xiàng)的索引,拿這些索引去 X 里找出對(duì)應(yīng)的行,再組合成一個(gè)新矩陣。

我們預(yù)期 X 過濾完是 3 x 2 列的矩陣,但不幸的是從 Out[81] 來看 numpy 這樣過濾完只會(huì)保留第一列的數(shù)據(jù),且把它轉(zhuǎn)化成了行向量,即變成了 1 x 3 的行向量。不知道你有沒有抓狂的感覺。如果按照 In [85] 的寫法,還會(huì)報(bào)錯(cuò)。如果要正確地過濾不同的列,需要寫成 In [86] 和 In [87] 的形式。但是即使寫成 In [86] 和 In [87] 的樣式,還是一樣把列向量轉(zhuǎn)化成了行向量。所以,要實(shí)現(xiàn)這個(gè)目的,得復(fù)雜到按照 In [88] 那樣才能達(dá)到目的。實(shí)際上,這個(gè)還達(dá)不到目的,因?yàn)槟抢锩鎸懥撕枚嘤簿幋a的數(shù)字,要處理通用的過濾情況,還需要寫個(gè)函數(shù)來實(shí)現(xiàn)。而這個(gè)任務(wù)在 matlab/octave 里只需要寫成 X(Y==1, :) 即可完美達(dá)成目的。

陷阱三:數(shù)值運(yùn)算句法混亂

機(jī)器學(xué)習(xí)算法里,經(jīng)常要做一些矩陣運(yùn)算。有時(shí)候要做叉乘,有時(shí)候要做點(diǎn)乘。我們看一下 numpy 是如何滿足這個(gè)需求的。

假設(shè) x, y, theta 的值如下,我們要先讓 x 和 y 點(diǎn)乘,再讓結(jié)果與 theta 叉乘,最后的結(jié)果我們期望的是一個(gè) 5 x 1 的列向量。

直觀地講,我們應(yīng)該會(huì)想這樣做:(x 點(diǎn)乘 y) 叉乘 theta。但很不幸,當(dāng)你輸入 x * y 時(shí)妥妥地報(bào)錯(cuò)。那好吧,我們這樣做總行了吧,x[:, 0] * y 這樣兩個(gè)列向量就可以點(diǎn)乘了吧,不幸的還是不行,因?yàn)?numpy 認(rèn)為這是 matrix,所以執(zhí)行的是矩陣相乘(叉乘),要做點(diǎn)乘,必須轉(zhuǎn)為 array 。

所以,我們需要象 In [39] 那樣一列列轉(zhuǎn)為 array 和 y 執(zhí)行點(diǎn)乘,然后再組合回 5 x 3 的矩陣。好不容易算出了 x 和 y 的點(diǎn)乘了,終于可以和 theta 叉乘了。

看起來結(jié)果還不錯(cuò),但實(shí)際上這里面也是陷阱重重。

In [45] 會(huì)報(bào)錯(cuò),因?yàn)樵?array 里 * 運(yùn)算符是點(diǎn)乘,而在 matrix 里 * 運(yùn)算符是叉乘。如果要在 array 里算叉乘,需要用 dot 方法??雌饋硖峁┝遂`活性,實(shí)際上增加了使用者的大腦負(fù)擔(dān)。而我們的需求在 matlab/octave 里只需要寫成 x .* y * theta ,直觀優(yōu)雅。

陷阱四:語法復(fù)雜,不自然

比如,我們要在一個(gè) 5 x 2 的矩陣的前面加一列全部是 1 的數(shù)據(jù),變成一個(gè) 5 x 3 的矩陣,我們必須這樣寫:

有興趣的人可以數(shù)數(shù) In [18] 里有多少個(gè)括號(hào),還別不服,括號(hào)寫少了妥妥地報(bào)錯(cuò)。而這個(gè)需求在 matlab/octave 里面只需要寫成[ones(5,1) x],瞬間腦袋不短路了,直觀優(yōu)雅又回來了。

結(jié)論

有人說 python 是機(jī)器學(xué)習(xí)和數(shù)據(jù)分析的新貴,但和專門的領(lǐng)域語言 matlab/octave 相比,用起來確實(shí)還是比較別扭的。當(dāng)然有些槽點(diǎn)是因?yàn)檎Z言本身的限制,比如 python 不支持自定義操作符,導(dǎo)致 numpy 的一些設(shè)計(jì)不夠優(yōu)雅和直觀,但默認(rèn)把列向量轉(zhuǎn)化為行向量的做法只能說是 numpy 本身的設(shè)計(jì)問題了。這或許就是 Andrew Ng 在他的 Machine Learning 課程里用 matlab/octave ,而不用 python 或其他的語言的原因吧。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7035

    瀏覽量

    89046
  • 矩陣
    +關(guān)注

    關(guān)注

    0

    文章

    423

    瀏覽量

    34548
  • 機(jī)器學(xué)習(xí)

    關(guān)注

    66

    文章

    8418

    瀏覽量

    132655

原文標(biāo)題:Numpy 隱含的四大陷阱,千萬別掉進(jìn)去了!

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    看了這么多論壇 還是這個(gè)論壇好啊...

    其他的論壇沒有這么多人,沒有這么快的更新.... 你們覺得呢?
    發(fā)表于 04-17 10:52

    電阻的作用居然有這么多?

    更改;可以用于在最短回流路徑斷裂時(shí)提供較小的回流路徑,減小干擾;可以有效的限制環(huán)路電流,使噪聲得到抑制;可以作為溫度補(bǔ)償器……零歐姆電阻竟然這么有用,小伙伴們有木有驚呆了呢~~  電阻的作用
    發(fā)表于 10-16 00:14

    這是spi讀華邦flash W24X16,我不明白這里這里怎么有這么多模式

    1 這是spi讀華邦flash W24X16,我不明白這里這里怎么有這么多模式,只覺得有主從模式和全雙工模式,不明白簡(jiǎn)單的雙向數(shù)據(jù)線/主模式和全雙工模式/主模式有什么區(qū)別?想請(qǐng)大家?guī)臀抑v解下這幅圖配置里的這么多模式相互之間的區(qū)別?2 還想問SPIx_NSS選擇硬件模式,主
    發(fā)表于 04-09 11:30

    AVR單片機(jī),在ICCAVR里輸入了幾行程序,可是運(yùn)行后有這么多錯(cuò)誤,請(qǐng)問是什么原因呢?

    我是單片機(jī)的初學(xué)者,今天按照課本在ICCAVR里輸入了幾行程序,可是運(yùn)行后有這么多錯(cuò)誤,請(qǐng)問是什么原因呢?
    發(fā)表于 10-25 11:46

    為什么roll一上電就飄了這么多?

    放在水平位置上校準(zhǔn)之后pitch還是挺準(zhǔn)的,roll一上電就飄了這么多,為什么??
    發(fā)表于 07-04 04:35

    為什么OLED初始化的時(shí)候要這么多命令?

    void OLED_Init(void)這個(gè)函數(shù)里面要寫的命令好多啊,不知道為什么初始化的時(shí)候要這么多命令?。??求解具體在數(shù)據(jù)手冊(cè)哪幾頁
    發(fā)表于 09-18 23:58

    什么是VBA?為什么這么多軟件支持VBA?

    什么是VBA?什么是VBS?二者有什么不同?為什么這么多軟件支持VBA?
    發(fā)表于 07-02 06:35

    STM32系統(tǒng)為什么要有時(shí)鐘?為什么有這么多個(gè)時(shí)鐘源

    STM32系統(tǒng)為什么要有時(shí)鐘?為什么有這么多個(gè)時(shí)鐘源?STM32系統(tǒng)時(shí)鐘的框架是由哪些部分組成的?
    發(fā)表于 11-22 07:00

    為什么有這么多編程語言呢

    關(guān)注+星標(biāo)公眾號(hào),不錯(cuò)過精彩內(nèi)容編排|strongerHuang微信公眾號(hào) |嵌入式專欄有很多初學(xué)者都會(huì)問:我到底是該學(xué)C語言,還是學(xué)C++,或者JAVA呢?為什么有這么多編程語言呢...
    發(fā)表于 01-12 06:34

    RK3399居然有這么強(qiáng)的解碼能力?

    的比較多,今天自己親自動(dòng)手測(cè)試下還是嚇了一跳,沒想到RK3399居然有這么強(qiáng)的解碼能力?一、什么是MPP?Media Process Platform (MPP) module directory
    發(fā)表于 09-08 16:42

    RK3399居然有這么強(qiáng)的解碼能力?

    的比較多,今天自己親自動(dòng)手測(cè)試下還是嚇了一跳,沒想到RK3399居然有這么強(qiáng)的解碼能力?一、什么是MPP?Media Process Platform (MPP) module directory
    發(fā)表于 10-09 18:02

    安卓8.0最新消息:安卓8.0初體驗(yàn),竟然這么流暢還有這么多黑科技功能

    安卓8.0初體驗(yàn),竟然這么流暢還有這么多黑科技功能
    發(fā)表于 04-13 09:00 ?3634次閱讀

    小墊圈,里面還有這么多名堂……

    小墊圈,里面還有這么多名堂……
    的頭像 發(fā)表于 07-02 11:40 ?2685次閱讀

    選AC-DC電源適配器還有這么多門道?看完才知道

    選AC-DC電源適配器還有這么多門道?看完才知道
    的頭像 發(fā)表于 07-02 11:40 ?6196次閱讀

    硬件電路設(shè)計(jì)有這么多坑,如何少走彎路?看大牛怎么說

    硬件電路設(shè)計(jì)有這么多坑,如何少走彎路?看大牛怎么說
    的頭像 發(fā)表于 11-27 17:34 ?654次閱讀