1. 程式人生 > >python cookbook 學習筆記 第三章 數字日期和時間(9) 大型資料運算

python cookbook 學習筆記 第三章 數字日期和時間(9) 大型資料運算

  • 大型資料運算
    -問題:
    • 需要在大資料集(比如陣列或網路)上面執行計算。
  • 解決方案:
    • 涉及到陣列的重量級運算,可以使用 Numpy 庫。Numpy 的一個主要特徵是他會給 Python 提 供一個數組物件,相比標準的 Python 列表更適合用來做數學運算。下面展示標準列表和 Numpy 陣列之間的差別:
x = [1, 2, 3, 4]
y = [5, 6, 7, 8]

print(x*2)
# [1, 2, 3, 4, 1, 2, 3, 4]
# print(x + 10)
# TypeError: can only concatenate list (not "int") to list
print(x + y)
# [1, 2, 3, 4, 5, 6, 7, 8]

import numpy as np

ax = np.array([1, 2, 3, 4])
ay = np.array([5, 6, 7, 8])
print(ax*2)  # [2 4 6 8]
print(ax + 10)  # [11 12 13 14]
print(ax + ay)  # [ 6  8 10 12]
  • 正如所見,兩種方案中陣列的基本數學運算結果並不相同。Numpy 中的標量運算(比如,ax*2
  • 或者 ax + 10)會作用在每一個元素上。另外當兩個操作都是陣列的時候執行元素對等位置計 算,並最終生成一個新的數字。
  • 對於整個陣列中所有元素同時執行數學運算可以使得作用在整個陣列上的函式運算簡單又快速。比如,想計算多項式的值,可以這樣做:
def f(x):
    return 3 * x**2 -2*x +7

f(ax) # [ 8 15 28 47]
  • Numpy 還為陣列操作提供了大量的通用函式,這些函式可以作為 math 模組中類似函式的替 代。比如:
np.sqrt(ax)
# [1.         1.41421356 1.73205081 2.        ]
np.cos(ax)
# [ 0.54030231 -0.41614684 -0.9899925  -0.65364362]
  • 使用這些通用函式要比迴圈陣列並使用 math 模組中的函式執行計算要快的多。因此,只要有 可能就儘量選擇 Numpy 的陣列方案。
  • 底層實現中,Numpy 陣列使用了 C 或者 Fortran 語言的機制分配記憶體。也就是說,它們是 一個非常大的連續的並由同類型資料組成的記憶體區域。所以,可以構造一個比普通 Python 列表 大的多的陣列。比如,想構建一個10000*10000的浮點數二維網格,很輕鬆:
grid = np.zeros(shape = (10000,10000), dtype = float)

print(grid)
"""
[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]
"""
  • 所有的操作還是會同時作用在所有元素上:
grid += 10
print(grid)
"""
[[10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 ...
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]]
"""
  • 關於 Numpy 有一個需要注意,那就是它擴充套件 Python 淚奔的索引功能,特別是對於多維陣列, 為了說明清楚,先構建一個簡單的二維陣列並試著做些試驗:
a = np.array([[1, 2, 3, 4],
             [5, 6, 7, 8],
             [9, 10, 11, 12]

])
print(a)
"""
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
"""
print(a[1])  # [5 6 7 8]
print(a[:,1])  # [ 2  6 10]
print(a[1:3,1:3])
"""
[[ 6  7]
 [10 11]]
"""
a[1:3, 1:3] += 10
print(a)
"""
[[ 1  2  3  4]
 [ 5 16 17  8]
 [ 9 20 21 12]]
"""
print(a + [100, 101, 102, 103])
"""
[[101 103 105 107]
 [105 117 119 111]
 [109 121 123 115]]
"""
print(a)
"""
[[ 1  2  3  4]
 [ 5 16 17  8]
 [ 9 20 21 12]]
"""
np.where(a < 10, a, 10)
"""
[[ 1  2  3  4]
 [ 5 10 10  8]
 [ 9 10 10 10]]
"""
  • 討論: Numpy 是 Python 領域中很多科學與工程庫的基礎,同時也是被廣泛使用的最大最復 雜的模組。即便如此,在剛開始的時候通過一些簡單例子和玩具程式,也能完成一些有趣的事情。
  • 通常我們匯入 Numpy 模組的時候會使用語句 import Numpy as np 。這樣在後面只要輸 入np就行了,省事不少。