close

接續這篇 Learning Python N-Dimensional Array–Part I

接下來, 輪到結構陣列上場

自定義一個資料結構 personType

‘names’: 相當於欄位名稱, 後面接字串陣列 [‘name’, ‘age’, ‘weight’]

‘formats’: 相當於資料型態, 後面接字串陣列 [‘S32’, ‘i’, ‘f’]

其中

S32:  長度32位元組的字串型態

i: 32位元整數型態(即np.int32)

i: 32位元單精準度浮點數型態(即np.float32)

personType = np.dtype({'names':['name', 'age','weight'],'formats':['S32','i','f']}, align=True)

定義變數a

a = np.array([('Peter', 18, 82.2), ('Jane', 20, 45.1)], dtype=personType)
 
a
Out[6]: 
array([('Peter', 18, 82.19999694824219), ('Jane', 20, 45.099998474121094)], 
      dtype={'names':['name','age','weight'], 'formats':['S32','<i4','<f4'], 'offsets':[0,32,36], 'itemsize':40, 'aligned':True})

觀察a變數中每個元素

a[1]
Out[8]: ('Jane', 20, 45.099998474121094)
 
a[0]
Out[9]: ('Peter', 18, 82.19999694824219)

猜猜看, 如果要取出某一組的某個欄位數值呢?

a[0][0]
Out[12]: 'Peter'
 
a[0][1]
Out[13]: 18
 
a[0][2]
Out[14]: 82.199997

另外, 也可以給定欄位名稱來取得內容

a[0]['name']
Out[28]: 'Peter'
 
a[0]['age']
Out[29]: 18
 
a[0]['weight']
Out[30]: 82.199997

如果要取得a變數中名字欄位中全部元素

a[0:]['name']
Out[31]: 
array(['Peter', 'Jane'], 
      dtype='|S32')

如果要找Peter這個人呢?

a[0:]['name']=='Peter'
Out[32]: array([ True, False], dtype=bool)

如何找某個人名字所對應的索引?

可以這樣下命令

np.nonzero(a[0:]['name']=='Peter')
Out[34]: (array([0]),)
 
np.nonzero(a[0:]['name']=='Jane')
Out[35]: (array([1]),)

後來, 看了一下書本[1], 發現如果要全取某個欄位,

這樣下指令更簡潔

a['name']
Out[36]: 
array(['Peter', 'Jane'], 
      dtype='|S32')
 
a['age']
Out[37]: array([18, 20])
 
a['weight']
Out[38]: array([ 82.19999695,  45.09999847], dtype=float32)

檔案輸出

image

image

// readBinFileDemo.cpp : 定義主控台應用程式的進入點。
//
 
#include "stdafx.h"
#include <stdio.h>
 
struct personType
{
    char name[32];
    int age;
    float weight;
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    personType p[2];
 
    FILE *fp;
    int i;
    fp = fopen("C:\\Python27\\Lib\\site-packages\\xy\\test.bin", "rb");
    fread(p, sizeof(struct personType), 2, fp);
    fclose(fp);
    for(i=0; i<2; i++)
    {
        printf("%s, %d, %f\n", p[i].name, p[i].age, p[i].weight);
    }
 
    return 0;
}

image

-----------------------------------------------------------------

import time
import math
import numpy as np
x = [i*0.001 for i in xrange(1000000)]
tic = time.clock()
for i, t in enumerate(x):
    x[i] = math.sin(t)
print "(1) Call math.sin in a for-loop: ", time.clock() - tic
    
x = [i*0.001 for i in xrange(1000000)]
x = np.array(x)    
tic = time.clock()
np.sin(x, x)
print "(2) Call np.sin: ", time.clock() - tic
 
 
x = [i*0.001 for i in xrange(1000000)]
tic = time.clock()
for i, t in enumerate(x):
    x[i] = np.sin(t)
print "(3) Call np.sin in a for-loop: ", time.clock() - tic

結果

(1) Call math.sin in a for-loop:  1.53591465722
(2) Call np.sin:  0.0960281567868
(3) Call np.sin in a for-loop:  3.91630797127

----------------------------------------------------

四則運算ufunc函式

a = np.arange(0, 4)
 
a
Out[40]: array([0, 1, 2, 3])
 
b = np.arange(1, 5)
 
b
Out[42]: array([1, 2, 3, 4])
 
np.add(a, b)
Out[43]: array([1, 3, 5, 7])

輸出結果, 寫回a

np.add(a, b, a)
Out[45]: array([1, 3, 5, 7])

但是如果輸出至一個未定義c, 會跳出錯誤

NameError                                 Traceback (most recent call last)
<ipython-input-44-374275167984> in <module>()
----> 1 np.add(a, b, c)
 
NameError: name 'c' is not defined

可是如果是下列這種方式, 可以算出結果

c = a+b
 
c
Out[48]: array([ 2,  5,  8, 11])

其中add參數定義如下

Parameters
----------
X : array_like
     First input array.
Y : array_like
     Second input array.
out : array_like
     An array to store the output. Must be the same shape as the
     output would have.

-----------------------------------------------

編輯檔案 testUfunc.py

import numpy as np
 
def linearrg(x, a, b):
    y = a*x+b
    return y
x = np.linspace(0, 2, 100)
y = np.array([linearrg(t, 1, 1) for t in x])
rgmodel = np.frompyfunc(linearrg, 3, 1)
y2 = rgmodel(x, 1, 1)

執行

run testUfunc.py

x

x
Out[64]: 
array([ 0.        ,  0.02020202,  0.04040404,  0.06060606,  0.08080808,
        0.1010101 ,  0.12121212,  0.14141414,  0.16161616,  0.18181818,
        0.2020202 ,  0.22222222,  0.24242424,  0.26262626,  0.28282828,
        0.3030303 ,  0.32323232,  0.34343434,  0.36363636,  0.38383838,
        0.4040404 ,  0.42424242,  0.44444444,  0.46464646,  0.48484848,
        0.50505051,  0.52525253,  0.54545455,  0.56565657,  0.58585859,
        0.60606061,  0.62626263,  0.64646465,  0.66666667,  0.68686869,
        0.70707071,  0.72727273,  0.74747475,  0.76767677,  0.78787879,
        0.80808081,  0.82828283,  0.84848485,  0.86868687,  0.88888889,
        0.90909091,  0.92929293,  0.94949495,  0.96969697,  0.98989899,
        1.01010101,  1.03030303,  1.05050505,  1.07070707,  1.09090909,
        1.11111111,  1.13131313,  1.15151515,  1.17171717,  1.19191919,
        1.21212121,  1.23232323,  1.25252525,  1.27272727,  1.29292929,
        1.31313131,  1.33333333,  1.35353535,  1.37373737,  1.39393939,
        1.41414141,  1.43434343,  1.45454545,  1.47474747,  1.49494949,
        1.51515152,  1.53535354,  1.55555556,  1.57575758,  1.5959596 ,
        1.61616162,  1.63636364,  1.65656566,  1.67676768,  1.6969697 ,
        1.71717172,  1.73737374,  1.75757576,  1.77777778,  1.7979798 ,
        1.81818182,  1.83838384,  1.85858586,  1.87878788,  1.8989899 ,
        1.91919192,  1.93939394,  1.95959596,  1.97979798,  2.        ])
y
Out[57]: 
array([ 1.        ,  1.02020202,  1.04040404,  1.06060606,  1.08080808,
        1.1010101 ,  1.12121212,  1.14141414,  1.16161616,  1.18181818,
        1.2020202 ,  1.22222222,  1.24242424,  1.26262626,  1.28282828,
        1.3030303 ,  1.32323232,  1.34343434,  1.36363636,  1.38383838,
        1.4040404 ,  1.42424242,  1.44444444,  1.46464646,  1.48484848,
        1.50505051,  1.52525253,  1.54545455,  1.56565657,  1.58585859,
        1.60606061,  1.62626263,  1.64646465,  1.66666667,  1.68686869,
        1.70707071,  1.72727273,  1.74747475,  1.76767677,  1.78787879,
        1.80808081,  1.82828283,  1.84848485,  1.86868687,  1.88888889,
        1.90909091,  1.92929293,  1.94949495,  1.96969697,  1.98989899,
        2.01010101,  2.03030303,  2.05050505,  2.07070707,  2.09090909,
        2.11111111,  2.13131313,  2.15151515,  2.17171717,  2.19191919,
        2.21212121,  2.23232323,  2.25252525,  2.27272727,  2.29292929,
        2.31313131,  2.33333333,  2.35353535,  2.37373737,  2.39393939,
        2.41414141,  2.43434343,  2.45454545,  2.47474747,  2.49494949,
        2.51515152,  2.53535354,  2.55555556,  2.57575758,  2.5959596 ,
        2.61616162,  2.63636364,  2.65656566,  2.67676768,  2.6969697 ,
        2.71717172,  2.73737374,  2.75757576,  2.77777778,  2.7979798 ,
        2.81818182,  2.83838384,  2.85858586,  2.87878788,  2.8989899 ,
        2.91919192,  2.93939394,  2.95959596,  2.97979798,  3.        ])
 
y2
Out[58]: 
array([1.0, 1.02020202020202, 1.0404040404040404, 1.0606060606060606,
       1.0808080808080809, 1.101010101010101, 1.121212121212121,
       1.1414141414141414, 1.1616161616161615, 1.1818181818181819,
       1.202020202020202, 1.2222222222222223, 1.2424242424242424,
       1.2626262626262625, 1.2828282828282829, 1.303030303030303,
       1.3232323232323233, 1.3434343434343434, 1.3636363636363638,
       1.3838383838383839, 1.404040404040404, 1.4242424242424243,
       1.4444444444444444, 1.4646464646464648, 1.4848484848484849,
       1.5050505050505052, 1.5252525252525253, 1.5454545454545454,
       1.5656565656565657, 1.5858585858585859, 1.606060606060606,
       1.6262626262626263, 1.6464646464646466, 1.6666666666666667,
       1.6868686868686869, 1.7070707070707072, 1.7272727272727273,
       1.7474747474747474, 1.7676767676767677, 1.787878787878788,
       1.8080808080808082, 1.8282828282828283, 1.8484848484848486,
       1.8686868686868687, 1.8888888888888888, 1.9090909090909092,
       1.9292929292929295, 1.9494949494949496, 1.9696969696969697,
       1.98989898989899, 2.0101010101010104, 2.0303030303030303,
       2.0505050505050506, 2.070707070707071, 2.090909090909091,
       2.111111111111111, 2.1313131313131315, 2.1515151515151514,
       2.1717171717171717, 2.191919191919192, 2.212121212121212,
       2.2323232323232327, 2.2525252525252526, 2.272727272727273,
       2.2929292929292933, 2.313131313131313, 2.3333333333333335,
       2.353535353535354, 2.3737373737373737, 2.393939393939394,
       2.4141414141414144, 2.4343434343434343, 2.4545454545454546,
       2.474747474747475, 2.494949494949495, 2.5151515151515156,
       2.5353535353535355, 2.5555555555555554, 2.575757575757576,
       2.595959595959596, 2.6161616161616164, 2.6363636363636367,
       2.6565656565656566, 2.676767676767677, 2.6969696969696972,
       2.717171717171717, 2.7373737373737375, 2.757575757575758,
       2.7777777777777777, 2.7979797979797985, 2.8181818181818183,
       2.8383838383838382, 2.858585858585859, 2.878787878787879,
       2.8989898989898992, 2.9191919191919196, 2.9393939393939394,
       2.95959595959596, 2.97979797979798, 3.0], dtype=object)
 
y.shape
Out[59]: (100,)
 
y2.shape
Out[60]: (100,)
 
 

繪圖

plot(x, y)
Out[63]: [<matplotlib.lines.Line2D at 0xeb06870>]

image

astype: 資料型態object轉float

y2.astype(np.float)
Out[67]: 
array([ 1.        ,  1.02020202,  1.04040404,  1.06060606,  1.08080808,
        1.1010101 ,  1.12121212,  1.14141414,  1.16161616,  1.18181818,
        1.2020202 ,  1.22222222,  1.24242424,  1.26262626,  1.28282828,
        1.3030303 ,  1.32323232,  1.34343434,  1.36363636,  1.38383838,
        1.4040404 ,  1.42424242,  1.44444444,  1.46464646,  1.48484848,
        1.50505051,  1.52525253,  1.54545455,  1.56565657,  1.58585859,
        1.60606061,  1.62626263,  1.64646465,  1.66666667,  1.68686869,
        1.70707071,  1.72727273,  1.74747475,  1.76767677,  1.78787879,
        1.80808081,  1.82828283,  1.84848485,  1.86868687,  1.88888889,
        1.90909091,  1.92929293,  1.94949495,  1.96969697,  1.98989899,
        2.01010101,  2.03030303,  2.05050505,  2.07070707,  2.09090909,
        2.11111111,  2.13131313,  2.15151515,  2.17171717,  2.19191919,
        2.21212121,  2.23232323,  2.25252525,  2.27272727,  2.29292929,
        2.31313131,  2.33333333,  2.35353535,  2.37373737,  2.39393939,
        2.41414141,  2.43434343,  2.45454545,  2.47474747,  2.49494949,
        2.51515152,  2.53535354,  2.55555556,  2.57575758,  2.5959596 ,
        2.61616162,  2.63636364,  2.65656566,  2.67676768,  2.6969697 ,
        2.71717172,  2.73737374,  2.75757576,  2.77777778,  2.7979798 ,
        2.81818182,  2.83838384,  2.85858586,  2.87878788,  2.8989899 ,
        2.91919192,  2.93939394,  2.95959596,  2.97979798,  3.        ])

----------------------------------------------------------------------

產生一個6x1向量a

a = np.arange(0, 60, 10).reshape(-1,1)
 
a
Out[2]: 
array([[ 0],
       [10],
       [20],
       [30],
       [40],
       [50]])
 
a.shape
Out[3]: (6, 1)

產生一個1x5向量b

b = np.arange(0,5)
 
b
Out[5]: array([0, 1, 2, 3, 4])
 
b.shape
Out[6]: (5,)
 

c=a+b

輸出陣列C的shape會以輸入a, b各個軸上的最大值進行擴充

 
c=a+b
 
c
Out[19]: 
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [40, 41, 42, 43, 44],
       [50, 51, 52, 53, 54]])

------------------------------------------------------------

另外用手動擴增資料來說明上述 c = a+b

a2 行方向擴增5筆

a2 = np.arange(0, 60,10).reshape(-1,1)
 
a2
Out[18]: 
array([[ 0],
       [10],
       [20],
       [30],
       [40],
       [50]])
 
a2 = a2.repeat(5, axis=1)
 
a2
Out[20]: 
array([[ 0,  0,  0,  0,  0],
       [10, 10, 10, 10, 10],
       [20, 20, 20, 20, 20],
       [30, 30, 30, 30, 30],
       [40, 40, 40, 40, 40],
       [50, 50, 50, 50, 50]])

b2 列方向擴增6筆

b2 = np.arange(0,5)
 
b2 = np.arange(0,5).reshape(1,5)
 
b2
Out[14]: array([[0, 1, 2, 3, 4]])
 
 
b2 = np.arange(0,5).reshape(1,5)
 
b2.shape
Out[15]: (1, 5)
 
 
b2 = b2.repeat(6, axis=0)
 
b2
Out[16]: 
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])

c2 = a2+ b2

c2 = a2 + b2
 
c2
Out[22]: 
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [40, 41, 42, 43, 44],
       [50, 51, 52, 53, 54]])

------------------------------------

當初在安裝Python(x, y)沒有勾選ETS(Enthought.mayavi會無法使用)

mayavi

image

 
from enthought.mayavi import mlab
WARNING:traits.has_traits:DEPRECATED: traits.has_traits.wrapped_class, 'the 'implements' class advisor has been deprecated. Use the 'provides' class decorator.
 
x, y = np.ogrid[-2:2:20j, -2:2:20j]
 
z = x*np.exp(-x**2-y**2)
 
pl = mlab.surf(x, y, z, warp_scale="auto")
 
mlab.axes(xlabel=' x', ylabel=' y', zlabel=' z')
Out[5]: <mayavi.modules.axes.Axes at 0x131af960>
 
mlab.outline(pl)
Out[6]: <mayavi.modules.outline.Outline at 0x132b5450>
 
mlab.show()

image

-----------------------------------------------------------------

向量沿著row或column進行加法運算

a = np.array([ 1, 2, 3])
 
a
Out[3]: array([1, 2, 3])
 
np.add.reduce(a, axis=0)
Out[4]: 6
 
np.add.reduce(a, axis=1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-2bca5397d7fd> in <module>()
----> 1 np.add.reduce(a, axis=1)

陣列沿著row或column進行加法運算

b = np.array([ [1, 2, 3], [4, 5, 6]])
 
b
Out[7]: 
array([[1, 2, 3],
       [4, 5, 6]])
 
np.add.reduce(b, axis=0)
Out[8]: array([5, 7, 9])
 
np.add.reduce(b, axis=1)
Out[9]: array([ 6, 15])

向量沿著row或column進行累加運算

a
Out[10]: array([1, 2, 3])
 
np.add.accumulate(a)
Out[11]: array([1, 3, 6])

陣列沿著row或column進行累加運算

b
Out[7]: 
array([[1, 2, 3],
       [4, 5, 6]])
 
np.add.accumulate(b, axis=0)
Out[12]: 
array([[1, 2, 3],
       [5, 7, 9]])
 
np.add.accumulate(b, axis=1)
Out[13]: 
array([[ 1,  3,  6],
       [ 4,  9, 15]])

多維陣列的索引存取

 
a=np.arange(3*4*5)
 
a
Out[2]: 
array([ 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, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59])
 
a=np.arange(3*4*5).reshape(3,4,5)
 
a
Out[4]: 
array([[[ 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],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]],
 
       [[40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])

取出第0層, 第1列, 第2行

a
Out[4]: 
array([[[ 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],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]],
 
       [[40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])
 
ind = [[0],[1],[2]]
 
a[ind]
Out[6]: array([7])

取出第1層, 第1列, 第2行

a
Out[4]: 
array([[[ 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],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]],
 
       [[40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])
 
ind2 = [[1],[1],[2]]
 
a[ind2]
Out[8]: array([27])

取出第0層, 第1列, 所有行

Out[9]: 
array([[[[ 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],
         [25, 26, 27, 28, 29],
         [30, 31, 32, 33, 34],
         [35, 36, 37, 38, 39]]],
 
 
       [[[40, 41, 42, 43, 44],
         [45, 46, 47, 48, 49],
         [50, 51, 52, 53, 54],
         [55, 56, 57, 58, 59]]]])
 
a[0, 1, :]
Out[13]: array([5, 6, 7, 8, 9])




參考資料

1. Python科學計算

2. http://docs.enthought.com/mayavi/mayavi/installation.html

3. numpy.ufunc.reduceat

arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(0) 人氣()