接續這篇 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)
檔案輸出
// 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;
}
-----------------------------------------------------------------
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>]
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
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()
-----------------------------------------------------------------
向量沿著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
留言列表