【轉】numpy:python資料領域的功臣
前言
numpy對python的意義非凡,在資料分析與機器學習領域為python立下了汗馬功勞。現在用python搞資料分析或機器學習經常使用的pandas、matplotlib、sklearn等庫,都需要基於numpy構建。毫不誇張地說,沒有numpy,python今天在資料分析與機器學習領域只能是捉襟見肘。
什麼是一門好的資料分析語言
資料分析面向的資料大多數是二維表。一門好的資料分析語言,首先需要能夠直接有個資料結構存下這個二維表,然後要配上一套成熟的類SQL的資料操作介面,最後要有一套好用的視覺化工具。R語言就是一個極好的典範:用內建的data.frame結構做資料的儲存;data.frame本身提供足夠強大的資料操作能力,另有dplyr、tidyr、data.table、plyr、reshape2等庫提供更好用更高效的資料操作能力;在繪圖上,除了基本的plot功能外,還提供了ggplot2這樣一套優雅的繪圖語言,還通過htmlwidget庫與javascript各種繪相簿建立了緊密的聯絡,讓視覺化的動態展示效果更進一步。Excel也是一個極好的例子,有單元格這種靈活的結構為資料儲存做支撐,有大量的函式實現靈活的操作,也有強大的繪圖系統。
python目前在資料分析領域也已經具備了相當可觀的能力,包括pandas庫實現的DataFrame結構,pandas本身提供的資料操作能力,matplotlib提供的資料視覺化能力,而這一切都離不開numpy庫。
什麼是一門好的機器學習語言
一般來講,一門好的機器學習語言在資料分析上也一定很吃得開,因為資料分析往往是機器學習的基礎。但是機器學習的要求更高,因為在模型訓練階段往往需要較為複雜的引數估計運算,因此語言需要具備較強的科學計算能力。科學計算能力,最核心的就是矩陣運算能力。關於矩陣運算能力,這篇文章對各種語言有很好的比較。
如果沒有numpy,python內部只能用list或array來表示矩陣。假如用list來表示[1,2,3],由於list的元素可以是任何物件,因此list中所儲存的是物件的指標,所以需要有3個指標和三個整數物件,比較浪費記憶體和CPU計算時間。python的array和list不同,它直接儲存數值,和C語言的一維陣列比較類似,但是不支援多維,表達形式很簡陋,寫科學計算的演算法很難受。numpy彌補了這些不足,其提供的ndarray是儲存單一資料型別的多維陣列,且採用預編譯好的C語言程式碼,效能上的表現也十分不錯。
python最流行的機器學習庫sklearn構建在numpy之上,提供了各種標準機器學習模型的訓練與預測介面,其中模型訓練介面的內部實現是基於numpy庫實現的。比如很常見的線性迴歸模型,引數估計呼叫的是numpy.linalg.lstsq函式。
numpy的核心結構:ndarray
以下內容摘錄自用Python做科學計算
a = np.array([[0,1,2],[3,4,5],[6,7,8]], dtype=np.float32)
ndarray是numpy的核心資料結構。我們來看一下ndarray如何在記憶體中儲存的:關於陣列的描述資訊儲存在一個資料結構中,這個結構引用兩個物件,一塊用於儲存資料的儲存區域和一個用於描述元素型別的dtype物件。
資料儲存區域儲存著陣列中所有元素的二進位制資料,dtype物件則知道如何將元素的二進位制資料轉換為可用的值。陣列的維數、大小等資訊都儲存在ndarray陣列物件的資料結構中。
strides中儲存的是當每個軸的下標增加1時,資料儲存區中的指標所增加的位元組數。例如圖中的strides為12,4,即第0軸的下標增加1時,資料的地址增加12個位元組:即a[1,0]的地址比a[0,0]的地址要高12個位元組,正好是3個單精度浮點數的總位元組數;第1軸下標增加1時,資料的地址增加4個位元組,正好是單精度浮點數的位元組數。
以下內容總結自Numpy官方文件Numpy basics
關於ndarray的索引方式,有以下幾個重點需要記住:
-
雖然x[0,2] = x0,但是前者效率比後者高,因為後者在應用第一個索引後需要先建立一個temporary array,然後再應用第二個索引,最後找到目標值。
-
分片操作不會引發copy操作,而是建立原ndarray的view;他們所指向的記憶體是同一片區域,無論是修改原ndarray還是修改view,都會同時改變二者的值。
-
index array和boolean index返回的是copy,不是view。
關於上面列舉的分片操作不會引發copy操作,我們來進一步探討一下。先看一下numpy的例子:
再來看一下R的例子:
可以看到numpy和R在矩陣的分片操作有不同的設計理念:在R裡分片操作會引起資料的複製,在numpy裡不會。事實上,R的設計理念很多時候可以用一句話來概括:copy on modify,一旦對資料有修改就會引起記憶體上的複製操作,這個操作要花不少時間,因此經常會聽到人們抱怨R費記憶體且速度慢。所以,我們可以看到numpy在處理這件事情上明顯要用心很多,根據場景設計了不同的策略,不是簡單地採用R的一刀切方式。當然,這也帶來了一些學習成本,需要對numpy足夠熟悉才能避免踩坑。R社群裡對copy on modify的哲學也有詬病並在努力改變,比如同是data.frame操作庫的data.table和dplyr,data.table效能比dplyr高很多,部分原因也是data.table規避了copy on modify的方式。
Structured Array
根據numpy的官方文件,定義結構化陣列有四種方式。本文采用字典方法,通過定義一個dtype物件實現,需要指定的鍵值有names和formats。
-
persontype = np.dtype({
-
'names': ['name', 'age', 'weight'],
-
'formats': ['S32', 'i', 'f']
-
})
-
a = np.array([("Zhang", 32, 75.5), ("Wang", 24, 65.2)], dtype=persontype)
我們用IPython的計時函式看一下提取資料的效率:
-
%timeit a[1]
-
%timeit a['name']
-
%timeit a[1]['name']
-
%timeit a['name'][1]
輸出結果如下:
-
The slowest run took 46.83 times longer than the fastest. This could mean that an intermediate result is being cached.
-
1000000 loops, best of 3: 153 ns per loop
-
The slowest run took 34.34 times longer than the fastest. This could mean that an intermediate result is being cached.
-
10000000 loops, best of 3: 174 ns per loop
-
The slowest run took 13.00 times longer than the fastest. This could mean that an intermediate result is being cached.
-
1000000 loops, best of 3: 1.08 µs per loop
-
The slowest run took 9.84 times longer than the fastest. This could mean that an intermediate result is being cached.
-
1000000 loops, best of 3: 412 ns per loop
從上面的結果,我們發現,獲取相同的資料有多種操作,不同的操作效能差別很大。我做了一個推測,純粹是瞎猜:numpy在建立結構化陣列時,將整個結構體連續儲存在一起,即按行儲存,因此a[1]
的速度最快;但是為了保證提取列的效率,對a['name']
建立了索引,因此a['name']
的效率也很高;但是這個索引只對整個a起作用,如果輸入只有a的一部分,仍然需要遍歷整個a,去提取出對應的資料,因此a[1]['name']
比a['name'][1]
的效率差很多。
關於作者:丹追兵:資料分析師一枚,程式語言python和R,使用Spark、Hadoop、Storm、ODPS。本文出自丹追兵的pytrafficR專欄,轉載請註明作者與出處:https://segmentfault.com/blog...
相關文章
- Python資料分析 – numpyPython
- Python---資料科學領域常用的15個Python包Python資料科學
- Python可以從事資料分析領域的工作嗎?Python
- Python資料分析之numpyPython
- Python資料分析 numpy 筆記Python筆記
- 【Python資料科學】之NumpyPython資料科學
- python-資料分析-Numpy-2Python
- Python資料分析與展示之『Numpy』Python
- 什麼是NumPy?Python中NumPy資料型別有哪些?Python資料型別
- 資料科學領域,你該選 Python 還是 R ?資料科學Python
- PyThon numpy中array如何轉list?Python
- 【轉】Python之Numpy詳細教程Python
- 深度學習領域的資料增強深度學習
- python-資料分析-NumPy的應用-1、基礎Python
- Python資料分析(一)--numpy全知全會Python
- Python資料分析--Numpy常用函式介紹(4)--Numpy中的線性關係和資料修剪壓縮Python函式
- 資料領域最強程式語言Python和R要合作了!Python
- Python資料分析--Numpy常用函式介紹(9)--Numpy中幾中常見的圖形Python函式
- Python資料分析--Numpy常用函式介紹(5)--Numpy中的相關性函式Python函式
- python-資料分析-Numpy-3、陣列的運算Python陣列
- 資料分析——numpy
- 為什麼Python是資料科學領域的首選語言?Python入門學習Python資料科學
- Python資料分析--Numpy常用函式介紹(3)Python函式
- Python資料分析--Numpy常用函式介紹(2)Python函式
- Python資料分析 | Numpy與1維陣列操作Python陣列
- 2024 年大資料領域的關鍵預測大資料
- 大資料領域三個大的技術方向大資料
- Python 爬取汽車領域問答語料(自用)Python
- 什麼是Python?Python涉及哪些領域?Python
- NumPy 資料型別資料型別
- numpy資料型別資料型別
- 人工智慧領域經典資料集人工智慧
- Python資料分析--工具安裝及Numpy介紹(1)Python
- Python資料分析工具庫-Numpy 陣列支援庫(一)Python陣列
- 資料處理02:Python數值計算包NumPyPython
- [譯] 使用 NumPy 和 Pandas 進行 Python 式資料清理Python
- 在資料科學領域,Python語言和R語言有何區別?資料科學PythonR語言
- python資料分析之Numpy資料庫第三期陣列的運算Python資料庫陣列