Numpy筆記(NumPy ndarray)

本篇筆記是根據(jù)學習《Python for data analysis》這本英文教程里的Numpy這一部分來記錄的筒饰。這本書在網(wǎng)上的評價還是很高的缴啡,里面講的東西也比較細壁晒,鑒于是英文的,所以我就打算只挑部分來看业栅,時間充裕的同學可以從頭到尾的細看一遍秒咐。

書的封面長這樣

Numpy,是Numerical Python的簡寫,它是Python里數(shù)字計算的最重要的一個基礎(chǔ)包碘裕。

The NumPy ndarray: A Multidimensional Array Object

Numpy ndarray:一個多維數(shù)組對象
Numpy 的一個關(guān)鍵的特點是其N-維數(shù)組對象携取,或者叫做ndarray,它是一個快速的帮孔,靈活的大數(shù)據(jù)python“容器”雷滋。Arrays使得你可以對整個block使用簡單的語法來進行數(shù)學計算文兢。舉個例子,導入Numpy并且生成一個小的隨機數(shù)組:

#首先進入ipython姆坚,具體方法請見我前一篇文章
#這里你可以使用shell,或者web界面兼呵,根據(jù)你喜好來
$ ipython
Python 3.7.6 (default, Jan  8 2020, 19:59:22)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import numpy as np #導入Numpy

In [2]: data = np.random.randn(2,3) #生成隨機數(shù)組兔辅,2個數(shù)組,每個里面3個元素

In [3]: data
Out[3]:
array([[ 0.01738749, -0.05367916,  0.72654692],
       [ 1.45506185, -0.71293169,  1.35346708]])

對數(shù)組進行數(shù)學運算:

In [4]: data*10
Out[4]:
array([[ 0.17387488, -0.53679156,  7.26546924],
       [14.55061854, -7.12931685, 13.53467077]])

In [5]: data+data
Out[5]:
array([[ 0.03477498, -0.10735831,  1.45309385],
       [ 2.91012371, -1.42586337,  2.70693415]])

ndarray是用于存放同種數(shù)據(jù)的多維“容器”维苔,也就是說懂昂,所有的元素必須是同樣的類型介时。每一個數(shù)組都有自己的shape,用shape可以查看每一個維度的大小潮尝;使用dtype可以查看數(shù)組內(nèi)的數(shù)據(jù)類型:

In [6]: data.shape
Out[6]: (2, 3)

In [7]: data.dtype
Out[7]: dtype('float64')

NOTE: Whenever you see “array,” “NumPy array,” or “ndarray” in the text,
with few exceptions they all refer to the same thing: the ndarray object.

Creating ndarrays

創(chuàng)建一個ndarray的最簡單的方法就是使用array功能。比如說:

In [8]: data1 = [6, 7.5, 8, 0, 1]

In [9]: arr1 = np.array(data1)

In [10]: arr1
Out[10]: array([6. , 7.5, 8. , 0. , 1. ])

或者你想創(chuàng)建嵌套序列勉失,比如等長列表,將會被轉(zhuǎn)換為多維數(shù)組:

In [11]: data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]

In [12]: arr2 = np.array(data2)

In [13]: arr2
Out[13]:
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

因為data2是一個由list組成的list顽素,所以arr2的shape是一個二維的數(shù)組徒蟆。你可以用ndimshape來檢查:

In [14]: arr2.ndim #看維度
Out[14]: 2

In [15]: arr2.shape
Out[15]: (2, 4)

In [16]: arr2.dtype
Out[16]: dtype('int64') #數(shù)組內(nèi)數(shù)據(jù)類型是int整數(shù)

另外,np.array還有很多其他的功能來創(chuàng)建新的arrays段审。比如說,它可以創(chuàng)建全是1或者全是0的array抑淫。還可以創(chuàng)建一個空的array姥闪,即沒有確定值:

In [17]: np.zeros(10) #創(chuàng)建全是0的一維數(shù)組
Out[17]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

In [18]: np.zeros((3,6)) #創(chuàng)建全是0的二維數(shù)組
Out[18]:
array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])

In [19]: np.empty((2,3,2)) #創(chuàng)建空數(shù)組
Out[19]:
array([[[6.95334423e-310, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000]],

       [[0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000]]])

有的時候,np.empty創(chuàng)建的空數(shù)組筐喳,返回值不是0,而是一堆亂七八糟的值荣月,也就是“garbage” values槐脏。

Data Types for ndarrays

在你創(chuàng)建一個ndarray的時候,你可以指定這個ndarray里的數(shù)據(jù)類型是什么顿天,比如說:

In [20]: arr1 = np.array([1, 2, 3], dtype=np.float64)

In [21]: arr1
Out[21]: array([1., 2., 3.])

In [22]: arr2 = np.array([1, 2, 3], dtype=np.int32)

In [23]: arr2
Out[23]: array([1, 2, 3], dtype=int32)

In [24]: arr1.dtype
Out[24]: dtype('float64')

In [25]: arr2.dtype
Out[25]: dtype('int32')

此外牌废,你也可以更改一個數(shù)組的數(shù)據(jù)類型:

In [26]: arr = np.array([1, 2, 3, 4, 5])

In [27]: arr.dtype
Out[27]: dtype('int64')

In [28]: float_arr = arr.astype(np.float64) #把整數(shù)類型改成浮點類型

In [29]: float_arr.dtype
Out[29]: dtype('float64')

相反咽白,你也可以把浮點類型改成整數(shù),但是小數(shù)部分就會被截掉:

In [30]: arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])

In [31]: arr
Out[31]: array([ 3.7, -1.2, -2.6,  0.5, 12.9, 10.1])

In [32]: arr.astype(np.int32)
Out[32]: array([ 3, -1, -2,  0, 12, 10], dtype=int32)

如果你的數(shù)組內(nèi)是字符串類型鸟缕,也可以使用這種方法進行轉(zhuǎn)換:

In [33]: numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)

In [34]: numeric_strings.astype(float)
Out[34]: array([ 1.25, -9.6 , 42.  ])

在使用numpy.string_進行數(shù)據(jù)類型轉(zhuǎn)換的時候需要注意,有的時候會在沒有任何提示下截斷你的數(shù)據(jù)授段。

Arithmetic(運算) with NumPy Arrays

array很重要,因為它們使你能夠?qū)?shù)據(jù)批量處理操作届搁,而不需要編寫任何for循環(huán)窍育。NumPy用戶稱之為向量化。任何算術(shù)必須在相同大小數(shù)組之間進行操作:

In [35]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])

In [36]: arr
Out[36]:
array([[1., 2., 3.],
       [4., 5., 6.]])

In [37]: arr*arr
Out[37]:
array([[ 1.,  4.,  9.],
       [16., 25., 36.]])

In [38]: 1/arr
Out[38]:
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])

In [39]: arr**0.5
Out[39]:
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

你還可以比較兩個不同的array的大小漱抓,這里比較的時候是數(shù)組之間相同位置進行比較:

In [40]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])

In [41]: arr2
Out[41]:
array([[ 0.,  4.,  1.],
       [ 7.,  2., 12.]])

In [42]: arr2>arr
Out[42]:
array([[False,  True, False],
       [ True, False,  True]])
Basic Indexing(索引) and Slicing(切片)

在Numpy里乞娄,你有很多種方法可以在data里選擇一個subset,或者選擇出某一個元素补胚。對于一維數(shù)組來說是非常簡單的:

In [43]: arr=np.arange(10)

In [44]: arr
Out[44]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [45]: arr[5]
Out[45]: 5

In [46]: arr[5:8]
Out[46]: array([5, 6, 7])

In [47]: arr[5:8]=12 #從索引的第5位到第7位改成12(這里涉及python的索引規(guī)則)

In [48]: arr
Out[48]: array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

對數(shù)組進行“切片”:

In [49]: arr_slice=arr[5:8]

In [50]: arr_slice
Out[50]: array([12, 12, 12])

對切出來的“片段”進行修改:

In [51]: arr_slice[1]=12345

In [52]: arr #對切片的修改會影響整個原始數(shù)組
Out[52]:
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,
           9])

對于二維數(shù)組來說:

In [53]: arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

In [54]: arr2d[2]
Out[54]: array([7, 8, 9])

In [55]: arr2d[0][2]
Out[55]: 3

In [56]: arr2d[0,2] #這樣的表示方法可以參考下面的示意圖來進行理解
Out[56]: 3

那如果是多維數(shù)組呢溶其?比如現(xiàn)在有一個2 × 2 × 3 array:

In [57]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

In [58]: arr3d
Out[58]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

In [59]: arr3d[0]
Out[59]:
array([[1, 2, 3],
       [4, 5, 6]])

更改多維數(shù)組里的數(shù)據(jù):

In [60]: old_values=arr3d[0].copy()

In [61]: arr3d[0]=42 #更改其中一個元素敦间,使得這個元素里的所有值都變成42

In [62]: arr3d
Out[62]:
array([[[42, 42, 42],
        [42, 42, 42]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

In [63]: arr3d[0]=old_values #再改回來

In [64]: arr3d
Out[64]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

對多維數(shù)組切片:

In [65]: arr3d[1,0]
Out[65]: array([7, 8, 9])
In [66]: arr2d
Out[66]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [67]: arr2d[:2]
Out[67]:
array([[1, 2, 3],
       [4, 5, 6]])
In [68]: arr2d[:2,1:] #在二維數(shù)組里取第0和1個索引對應(yīng)的list廓块,然后在這兩個list里取從索引1開始,到最后的元素
Out[68]:
array([[2, 3],
       [5, 6]])

In [69]: arr2d[1,:2] #取索引是1的list带猴,然后在這個list里取從開始到索引為2(不包括2)的元素
Out[69]: array([4, 5])

有關(guān)二維數(shù)組的切片的索引位置,可以參考下圖:

將數(shù)組里小于0的數(shù)都設(shè)置為0:

In [70]: data = np.random.randn(7, 4)

In [71]: data
Out[71]:
array([[ 1.07484753, -1.37075898, -1.76641029,  1.39686773],
       [ 1.12808743,  0.38325471,  2.26384631,  1.21861537],
       [-0.37522887, -1.2066686 , -0.07729884,  1.76493675],
       [ 0.51771666,  0.14024697,  0.91802525,  0.88580838],
       [-0.17494945, -0.14744639,  0.82242766, -0.060019  ],
       [ 1.11820368, -1.18942934,  1.34140358, -0.9074736 ],
       [ 0.01312651, -2.17228966,  0.97890648,  1.51395293]])

In [72]: data[data<0]=0

In [73]: data
Out[73]:
array([[1.07484753, 0.        , 0.        , 1.39686773],
       [1.12808743, 0.38325471, 2.26384631, 1.21861537],
       [0.        , 0.        , 0.        , 1.76493675],
       [0.51771666, 0.14024697, 0.91802525, 0.88580838],
       [0.        , 0.        , 0.82242766, 0.        ],
       [1.11820368, 0.        , 1.34140358, 0.        ],
       [0.01312651, 0.        , 0.97890648, 1.51395293]])
Fancy Indexing

花式索引是NumPy采用的術(shù)語,用于描述對整數(shù)數(shù)組進行索引:

In [74]: arr=np.empty((8,4)) #比如先創(chuàng)建一個8*4的空數(shù)組

In [75]: arr #這就是上面說到的口予,有時候你創(chuàng)建的空數(shù)組不是每次都會是0
Out[75]:
array([[ 6.95334381e-310,  0.00000000e+000,  6.93002310e-310,
         4.34669976e-118],
       [ 6.93002307e-310,  6.93002310e-310,  1.04440620e+181,
         6.93002307e-310],
       [ 6.93002310e-310, -1.76250980e-304,  6.93002307e-310,
         6.93002310e-310],
       [ 8.10582968e-283,  6.93002307e-310,  6.93002310e-310,
         2.58280046e+280],
       [ 6.93002308e-310,  6.93002461e-310,  1.20122413e+036,
         6.93002307e-310],
       [ 6.93002461e-310,  6.39556658e-245,  6.93002307e-310,
         6.93002461e-310],
       [ 9.69473502e+012,  6.93002307e-310,  6.93002461e-310,
         2.99497312e+029],
       [ 6.93002307e-310,  6.93002461e-310, -2.36433447e+212,
         6.93002307e-310]])

In [76]: for i in range(8): #給這個空數(shù)組賦值
    ...:     arr[i]=i
    ...:

In [77]: arr
Out[77]:
array([[0., 0., 0., 0.],
       [1., 1., 1., 1.],
       [2., 2., 2., 2.],
       [3., 3., 3., 3.],
       [4., 4., 4., 4.],
       [5., 5., 5., 5.],
       [6., 6., 6., 6.],
       [7., 7., 7., 7.]])

選擇你想提取的subset沪停,并按照特定順序排列:

In [78]: arr[[4,3,0,6]]
Out[78]:
array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])

In [79]: arr[[-3,-5,-7]] #負數(shù)表示從倒數(shù)順序來取subset
Out[79]:
array([[5., 5., 5., 5.],
       [3., 3., 3., 3.],
       [1., 1., 1., 1.]])
通用函數(shù)
In [1]: import numpy as np

In [2]: arr = np.arange(10)

In [3]: arr
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [4]: np.sqrt(arr)   #計算每一個元素的開方
Out[4]:
array([0.        , 1.        , 1.41421356, 1.73205081, 2.        ,
       2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])

In [5]: np.exp(arr)     #numpy.exp():返回e的冪次方裳涛,e是一個常數(shù)為2.71828
Out[5]:
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
       5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
       2.98095799e+03, 8.10308393e+03])
Unique

針對一維數(shù)組众辨,這個函數(shù)是把數(shù)組里“不重復的”元素挑選出來。

In [11]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])

In [12]: np.unique(names)
Out[12]: array(['Bob', 'Joe', 'Will'], dtype='<U4')

In [13]: ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])

In [14]: np.unique(ints)
Out[14]: array([1, 2, 3, 4])
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載技肩,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者浮声。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泳挥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剧浸,老刑警劉巖矗钟,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躬它,居然都是意外死亡东涡,警方通過查閱死者的電腦和手機冯吓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門组贺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祖娘,“玉大人失尖,你說我怎么就攤上這事渐苏。” “怎么了胧辽?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵公黑,是天一觀的道長摄咆。 經(jīng)常有香客問我人断,道長,這世上最難降的妖魔是什么恶迈? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任暇仲,我火速辦了婚禮步做,結(jié)果婚禮上奈附,老公的妹妹穿的比我還像新娘。我一直安慰自己将鸵,他們只是感情好佑颇,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著痒筒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凸克。 梳的紋絲不亂的頭發(fā)上闷沥,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天咐容,我揣著相機與錄音,去河邊找鬼戳粒。 笑死,一個胖子當著我的面吹牛奄妨,可吹牛的內(nèi)容都是我干的苹祟。 我是一名探鬼主播砸抛,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼直焙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奔誓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤和措,失蹤者是張志新(化名)和其女友劉穎蜕煌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幌绍,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年颁独,在試婚紗的時候發(fā)現(xiàn)自己被綠了伪冰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡靠柑,死狀恐怖吓懈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耻警,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布腮恩,位于F島的核電站温兼,受9級特大地震影響秸滴,放射性物質(zhì)發(fā)生泄漏募判。R本人自食惡果不足惜咒唆,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一内颗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恨溜,春花似錦、人聲如沸糟袁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽槽惫。三九已至,卻和暖如春仿耽,著一層夾襖步出監(jiān)牢的瞬間各薇,已是汗流浹背项贺。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工开缎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奕删。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓治宣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侮邀。 傳聞我的和親對象是個殘疾皇子贝润,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345