本篇文章是python數(shù)據(jù)探索系列掃盲文章的第一篇只泼,主要和各位朋友探討一下numpy瞬欧,后續(xù)文章會陸續(xù)介紹pandas以及Matplotlib坦仍。如有疏漏不當(dāng)?shù)牡胤胶孛ィ埩粞曰蛩叫盼摇9餐M(jìn)步载绿!
在處理一些數(shù)據(jù)時粥诫,我們常常會需要處理數(shù)組,而使用原生的array顯然會比較慢崭庸。numpy有許多用 C 語言實現(xiàn)的底層函數(shù)怀浆,所以我們選擇使用numpy進(jìn)行數(shù)據(jù)探索。
一怕享、數(shù)組基礎(chǔ)
首先执赡,我們明確一下研究對象——數(shù)組。在numpy里我們操作的對象就是ndarrays多維數(shù)組函筋。我們假想一個使用環(huán)境沙合,比如讀取一個股票數(shù)據(jù)。為了
更快的使用體驗跌帐,我們決定使用numpy首懈。那么我們怎么讀取這份數(shù)據(jù)呢?這涉及到numpy創(chuàng)建數(shù)組吧!我們來講一下:
# 1D Array
a = np.array([0, 1, 2, 3, 4])
b = np.array((0, 1, 2, 3, 4))
c = np.arange(5)
d = np.linspace(0, 2*np.pi, 5)
print(a) # >>>[0 1 2 3 4]
print(b) # >>>[0 1 2 3 4]
print(c) # >>>[0 1 2 3 4]
print(d) # >>>[ 0. 1.57079633 3.14159265 4.71238898 6.28318531]
print(a[3]) # >>>3
我們還可以使用dtype為數(shù)據(jù)指定類型谨敛。比如:
a = np.array([2,23,4],dtype=np.int)
print(a.dtype)
# int 64
可以指定如float(64位)int32究履、int32等等數(shù)據(jù)類型。
還有一些特殊的數(shù)組脸狸,比如全零
a = np.zeros((3,4)) # 數(shù)據(jù)全為0最仑,3行4列
"""
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
"""
創(chuàng)建全一數(shù)組, 同時也能指定這些特定數(shù)據(jù)的 dtype:
a = np.ones((3,4),dtype = np.int) # 數(shù)據(jù)為1,3行4列
"""
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]])
"""
怎么讀取文件呢肥惭?一句代碼可以搞定盯仪,a就是numpy數(shù)組:
a = numpy.loadtxt('haha.txt')
舉個例子。
以載入蘋果公司的歷史股價數(shù)據(jù)為例蜜葱。股價數(shù)據(jù)存儲在CSV文件中,第一列為股票代碼以標(biāo)識股票(蘋果公司股票代碼為AAPL)耀石,第二列為dd-mm-yyyy格式的日期牵囤,第三列為空爸黄,隨后各列依次是開盤價、最高價揭鳞、最低價和收盤價炕贵,最后一列為當(dāng)日的成交量。下面為一行數(shù)據(jù):
AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
將收盤價和成交量分別載入到兩個數(shù)組中野崇,代碼如下所示:
>>> a,b=np.loadtxt("./data.csv",
... delimiter=',',usecols=(6,7),unpack=True)
>>> print a
[ 336.1 339.32 345.03 344.32 343.44 346.5 351.88 355.2 358.16
354.54 356.85 359.18 359.9 363.13 358.3 350.56 338.61 342.62
342.88 348.16 353.21 349.31 352.12 359.56 360. 355.36 355.76
352.47 346.67 351.99]
delimiter=’,’表示用逗號作為分隔符称开,usecols=(6,7)表示一個元組,用來指明獲取哪些列的字段乓梨,unpack=True是說拆分存儲不同的數(shù)據(jù)鳖轰,即分別將收盤價和日成交量賦值給a和b。
現(xiàn)在菜已經(jīng)洗好了扶镀,我們需要進(jìn)行進(jìn)一步的清洗蕴侣。我們要做到“指哪打哪”,挑選我們真正需要的東西臭觉。
我們先定義一個多維矩陣昆雀。多維數(shù)組切片比一維數(shù)組要復(fù)雜一點,同時它也是你在用 NumPy 的時候經(jīng)常會用到的蝠筑。
# MD Array,
a = np.array([[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]])
print(a[2,4]) # >>>25
我們開始挑選我們需要的數(shù)據(jù)狞膘,其實無非就是某些數(shù),某些行什乙,某些列客冈,某些塊。
# MD slicing
print(a[0, 1:4]) # >>>[12 13 14]
print(a[1:4, 0]) # >>>[16 21 26]
print(a[::2,::2]) # >>>[[11 13 15]
# [21 23 25]
# [31 33 35]]
print(a[:, 1]) # >>>[12 17 22 27 32]
用一張圖來說明情況稳强。
二场仲、數(shù)組信息獲取
還是承接上文的數(shù)據(jù),我們獲得了“我們想要的數(shù)組”退疫,那么我們總得看看我們切的數(shù)據(jù)對不對吧渠缕?那最簡單的方法就是獲取下信息看看。我們可以這么做:
# Array properties
a = np.array([[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]])
print(type(a)) # >>><class 'numpy.ndarray'>
print(a.dtype) # >>>int64
print(a.size) # >>>25
print(a.shape) # >>>(5, 5)
print(a.itemsize) # >>>8
print(a.ndim) # >>>2
print(a.nbytes) # >>>200
其它信息都很直觀褒繁,'itemsize' 屬性是每一個條目所占的字節(jié)亦鳞。這個數(shù)組的數(shù)據(jù)類型是 int64,一個 int64 的大小是 64 比特棒坏,8 比特為 1 字節(jié)燕差,64 除以 8 就得到了它的字節(jié)數(shù),8 字節(jié)坝冕。
三徒探、使用數(shù)組
既然獲得的我們想要的數(shù)組。接下來我們就能對數(shù)組進(jìn)行操作了喂窟。
那么有哪些運(yùn)算呢测暗?我們來看看基本的操作央串。
# Basic Operators
>>> import numpy as np
>>> a = np.arange(25)
>>> print(a)
[ 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]
>>> a = a.reshape((5,5))
>>> print(a)
[[ 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]]
>>> b = np.array([10, 62, 1, 14, 2, 56, 79, 2, 1, 45,
... 4, 92, 5, 55, 63, 43, 35, 6, 53, 24,
... 56, 3, 56, 44, 78])
>>> b = b.reshape((5,5))
>>> print(a + b)
[[ 10 63 3 17 6]
[ 61 85 9 9 54]
[ 14 103 17 68 77]
[ 58 51 23 71 43]
[ 76 24 78 67 102]]
>>> print(a - b)
[[-10 -61 1 -11 2]
[-51 -73 5 7 -36]
[ 6 -81 7 -42 -49]
[-28 -19 11 -35 -5]
[-36 18 -34 -21 -54]]
>>> print(a * b)
[[ 0 62 2 42 8]
[ 280 474 14 8 405]
[ 40 1012 60 715 882]
[ 645 560 102 954 456]
[1120 63 1232 1012 1872]]
>>> print(a / b)
[[0. 0.01612903 2. 0.21428571 2. ]
[0.08928571 0.07594937 3.5 8. 0.2 ]
[2.5 0.11956522 2.4 0.23636364 0.22222222]
[0.34883721 0.45714286 2.83333333 0.33962264 0.79166667]
[0.35714286 7. 0.39285714 0.52272727 0.30769231]]
>>> print(a ** 2)
[[ 0 1 4 9 16]
[ 25 36 49 64 81]
[100 121 144 169 196]
[225 256 289 324 361]
[400 441 484 529 576]]
>>> print(a < b)
[[ True True False True False]
[ True True False False True]
[False True False True True]
[ True True False True True]
[ True False True True True]]
>>> print(a.dot(b))
[[ 417 380 254 446 555]
[1262 1735 604 1281 1615]
[2107 3090 954 2116 2675]
[2952 4445 1304 2951 3735]
[3797 5800 1654 3786 4795]]
除了 dot() 之外,這些操作符都是對數(shù)組進(jìn)行逐元素運(yùn)算碗啄。比如 (a, b, c) + (d, e, f) 的結(jié)果就是 (a+d, b+e, c+f)质和。它將分別對每一個元素進(jìn)行配對,然后對它們進(jìn)行運(yùn)算稚字。它返回的結(jié)果是一個數(shù)組饲宿。注意,當(dāng)使用邏輯運(yùn)算符比如 “<” 和 “>” 的時候胆描,返回的將是一個布爾型數(shù)組瘫想。dot() 函數(shù)計算兩個數(shù)組的點積。它返回的是一個標(biāo)量(只有大小沒有方向的一個值)而不是數(shù)組袄友。
dot() 函數(shù)有時候也稱為點積殿托。理解這個函數(shù)的最好方法就是看下邊它的計算過程。
盜圖一張剧蚣,在此感謝編程派的作者支竹!
其它一些運(yùn)算符:
# dot, sum, min, max, cumsum
a = np.arange(10)
print(a.sum()) # >>>45
print(a.min()) # >>>0
print(a.max()) # >>>9
print(a.cumsum()) # >>>[ 0 1 3 6 10 15 21 28 36 45]
cumsum() 就是一個累加計算并且保存每次累加的結(jié)果,返回值就是包含所有累加結(jié)果的一個列表鸠按。比如 np.array([1, 2, 3, 4, 5]).cumsum() = [1, 3, 6, 10, 15]
四礼搁、高級索引
這個直接看例子吧!
# Fancy indexing
a = np.arange(0, 100, 10)
indices = [1, 5, -1]
b = a[indices]
print(a) # >>>[ 0 10 20 30 40 50 60 70 80 90]
print(b) # >>>[10 50 90]
布爾屏蔽(boolean masking)
布爾屏蔽是一個奇妙的特性目尖,它允許我們根據(jù)指定條件獲取數(shù)組中的元素馒吴。簡單說,就是設(shè)置一個約束條件比如:mask=(a<0)用mask做下標(biāo)瑟曲,這樣在檢索的時候饮戳,都會檢查一遍約束條件,這樣就可以選出想要的結(jié)果洞拨。
# Boolean masking
import matplotlib.pyplot as plt
a = np.linspace(0, 2 * np.pi, 50)
b = np.sin(a)
plt.plot(a,b)
mask = b >= 0
plt.plot(a[mask], b[mask], 'bo')
mask = (b >= 0) & (a <= np.pi / 2)
plt.plot(a[mask], b[mask], 'go')
plt.show()
上邊的代碼展示了實現(xiàn)布爾屏蔽扯罐。你需要做的就是傳遞給數(shù)組一個與它有關(guān)的條件式,然后它就會返回給定條件下為真的值烦衣。
上邊的例子將會生成下邊這幅圖歹河,上面的點點就是篩選出的結(jié)果:
缺省索引是從多維數(shù)組的第一維獲取索引和切片便捷方法。例如花吟,你有一個數(shù)組 a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]秸歧,那么 a[3] 將會返回數(shù)組第一維中索引值為 3 的元素,這里的結(jié)果是 4衅澈。
# Incomplete Indexing
a = np.arange(0, 100, 10)
b = a[:5]
c = a[a >= 50]
print(b) # >>>[ 0 10 20 30 40]
print(c) # >>>[50 60 70 80 90]
where() 函數(shù)是另外一個根據(jù)條件返回數(shù)組中的值的有效方法键菱。只需要把條件傳遞給它,它就會返回一個使得條件為真的元素的列表矾麻。
# Where
a = np.arange(0, 100, 10)
b = np.where(a < 50)
c = np.where(a >= 50)[0]
print(b) # >>>(array([0, 1, 2, 3, 4]),)
print(c) # >>>[5 6 7 8 9]
參考:
編程派教程
http://codingpy.com/article/an-introduction-to-numpy/
莫煩的教程
https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/