numpy教程:陣列建立
Array creation routines
There are 5 general mechanisms for creating arrays:
- Conversion from other Python structures (e.g., lists, tuples)
- Intrinsic numpy array array creation objects (e.g., arange, ones, zeros,etc.)
- Reading arrays from disk, either from standard or custom formats
- Creating arrays from raw bytes through the use of strings or buffers
- Use of special library functions (e.g., random)
可以通過dtype引數在建立時指定元素型別
宣告一個沒有初值的ndarray型別的變數
topic_list = ndarray([word_num, topic_num], dtype=object)
如果這樣topic_list = ndarray([word_num, topic_num], dtype=str)就會報錯:ValueError: data-type with unspecified variable length
自定義陣列元素型別
一個元素包含多個型別
b = np.array([(1, 2.0, 'Hello'), (2, 3.0, 'World')], dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')]) print(b)numpy陣列中新增元素型別為list
ul_array = np.zeros([num_users, len(locs)], dtype=list)
在NumPy中使用動態陣列
NumPy的ndarray陣列物件不能像list一樣動態地改變其大小,在做資料採集時很不方便。本文介紹如何通過np.frombuffer()實現動態陣列。
Ones and zeros
empty(shape[, dtype, order]) | Return a new array of given shape and type, without initializing entries.預設拷貝輸入資料 |
empty_like(a[, dtype, order, subok]) | Return a new array with the same shape and type as a given array.當輸入已經是一個ndarray時就不拷貝。 |
eye(N[, M, k, dtype]) | Return a 2-D array with ones on the diagonal and zeros elsewhere. |
Return the identity array. | |
ones(shape[, dtype, order]) | Return a new array of given shape and type, filled with ones. |
ones_like(a[, dtype, order, subok]) | Return an array of ones with the same shape and type as a given array. |
zeros(shape[, dtype, order]) | Return a new array of given shape and type, filled with zeros. |
zeros_like(a[, dtype, order, subok]) | Return an array of zeros with the same shape and type as a given array. |
full(shape, fill_value[, dtype, order]) | Return a new array of given shape and type, filled with fill_value. |
full_like(a, fill_value[, dtype, order, subok]) | Return a full array with the same shape and type as a given array. |
通常,陣列的元素開始都是未知的,但是它的大小已知。因此,NumPy提供了一些使用佔位符建立陣列的函式。這最小化了擴充套件陣列的需要和高昂的運算代價。
生成bool陣列
np.ones(..,dtype = bool)
bool陣列取反
~bool_arr
生成無窮大陣列矩陣
M_ic = np.full([3,4], fill_value=sys.maxsize, dtype=np.int64)
ones([...])
全一的矩陣, 如ones([3,4])會產生全1的3x4階矩陣; #這裡的3,4要用[]或者()括起來,否則會出現錯誤:TypeError: data type not understood
zeros([....])
全0的矩陣;
不要使用這樣的方式初始化字串陣列:
s = np.zeros([2,2], dtype='str')print(s, s.dtype) s[:, 0] = '123' print(s, s.dtype)[['' '']
['' '']] <U1
[['1' '']
['1' '']] <U1
這樣初始化的字串陣列的字串是1位的U1,而‘123’是U3,這樣就不能賦值了。要使用
s = np.ndarray([2, 2], dtype=object)這樣就可以了。
empty( (2,3) )
array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
[ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
Note:與zeros唯一不同的是 np.empty裡面不是資料,而是給資料分配的空間地址
identity(n)
建立n*n的單位陣,這隻能是一個方陣。
eye(N,M=None,k=0)
建立一個對角線是1其餘值為0的矩陣,用k指定對角線的位置。M預設None
like函式
numpy中還提供了幾個like函式,即按照某一個已知的陣列的規模(幾行幾列)建立同樣規模的特殊陣列: zeros_like, ones_like, empty_like
Note:random.random([...]): 產生隨機矩陣,如random.random([2,3])產生一個2x3維的隨機數[Python和numpy生成隨機數]
From existing data
array(object[, dtype, copy, order, subok, ndmin]) | Create an array. |
asarray(a[, dtype, order]) | Convert the input to an array. |
asanyarray(a[, dtype, order]) | Convert the input to an ndarray, but pass ndarray subclasses through. |
Return a contiguous array in memory (C order). | |
asmatrix(data[, dtype]) | Interpret the input as a matrix. |
copy(a[, order]) | Return an array copy of the given object. |
frombuffer(buffer[, dtype, count, offset]) | Interpret a buffer as a 1-dimensional array. |
fromfile(file[, dtype, count, sep]) | Construct an array from data in a text or binary file. |
fromfunction(function, shape, **kwargs) | Construct an array by executing a function over each coordinate. |
fromiter(iterable, dtype[, count]) | Create a new 1-dimensional array from an iterable object. |
fromstring(string[, dtype, count, sep]) | A new 1-D array initialized from raw binary or text data in a string. |
loadtxt(fname[, dtype, comments, delimiter, ...]) | Load data from a text file. |
array和asarray函式:傳遞Python的序列物件建立陣列
從列表建立
>>> from numpy import *
>>> a = array([[1,2.2,3],[4,5,6]])
>>> a.ndim
2
>>> a.size
6
>>> type(a)
<type numpy.ndarray>
從字串建立
a = '****abc*.....'l = array(list(a))
id_card_str = '42028118921027721' id_card = np.array(list(id_card_str), dtype=int) print(id_card) #[4 2 0 2 8 1 1 8 9 2 1 0 2 7 7 2 1]
Note: 這種方法好像比下面的np.fromstring實用,fromstring指定轉換型別時會將'4'轉換成對應ASIC數值52。
多層巢狀的序列建立多維陣列
First mode, buffer is None: >>> np.ndarray(shape=(2,2), dtype=float, order=’F’) array([[ -1.13698227e+002, 4.25087011e-303], [ 2.88528414e-306, 3.27025015e-309]]) #random Second mode: >>> np.ndarray((2,), buffer=np.array([1,2,3]), offset=np.int_().itemsize, dtype=int) # offset = 1*itemsize, i.e. skip first element array([2, 3])
上面的例子都是先建立一個Python序列,然後通過array函式將其轉換為陣列,這樣做顯然效率不高。
如果傳入一個實數
import numpy as np x = 9.8 y = np.asarray(x) # y = np.array(x) print('type(y):', type(y)) print('y.ndim', y.ndim) print('y', y) print('y[0]', y[0]) # 出錯type(y): <class 'numpy.ndarray'>
y.ndim 0
y 9.8
維度竟然是0維,型別卻還是ndarray。
所以list轉換2維陣列時可以這樣
ts_array = np.asarray(x).reshape([-1, 1]) if np.asarray(x).ndim <= 1 else np.asarray(x)
array和asarray的區別和聯絡
def asarray(a, dtype=None, order=None): return array(a, dtype, copy=False, order=order)the main difference is that array (by default) will make a copy of the object, while asarray will not unless necessary.
b = array(a)當你傳入一個ndarray引數a時,修改b的值不會改變a的值;而b = asarray(a)會改變a的值。
Note: 如果傳入的引數a是一個python列表,則asarray也不會改變a的值,好像只是numpy內部型別如ndarray才可以的。
array和ndarray的區別和聯絡
np.array is just a convenience function to create an ndarray, it is not a class itself.
You can also create an array using np.ndarray
, but it is not the recommended way. From the docstring of np.ndarray
: Arrays should be constructed using array
, zeros
or empty
... The parameters given here refer to a low-level method (ndarray(...)
) for instantiating an array.
Note: ndarray只是建立了一個ndarray物件,並沒有傳入資料的機制。傳入的引數是ndarray物件的維度(初始化資料為隨機的無窮小)。
使用frombuffer, fromstring, fromfile等函式從位元組序列建立陣列
下面以fromstring為例:
>>> s = "abcdefgh"
Python的字串實際上是位元組序列,每個字元佔一個位元組,因此如果從字串s建立一個8bit的整數陣列的話,所得到的陣列正好就是字串中每個字元的ASCII編碼:
>>> np.fromstring(s, dtype=np.int8) array([ 97, 98, 99, 100, 101, 102, 103, 104], dtype=int8)
如果從字串s建立16bit的整數陣列,那麼兩個相鄰的位元組就表示一個整數,把位元組98和位元組97當作一個16位的整數,它的值就是98*256+97 = 25185。可以看出記憶體中是以little endian(低位位元組在前)方式儲存資料的。
>>> np.fromstring(s, dtype=np.int16) array([25185, 25699, 26213, 26727], dtype=int16) >>> 98*256+97 25185
如果把整個字串轉換為一個64位的雙精度浮點數陣列,那麼它的值是:
>>> np.fromstring(s, dtype=np.float) array([ 8.54088322e+194])
顯然這個例子沒有什麼意義,但是可以想象如果我們用C語言的二進位制方式寫了一組double型別的數值到某個檔案中,那們可以從此檔案讀取相應的資料,並通過fromstring函式將其轉換為float64型別的陣列。
我們可以寫一個Python的函式,它將陣列下標轉換為陣列中對應的值,然後使用此函式建立陣列:
>>> def func(i): ... return i%4+1 ... >>> np.fromfunction(func, (10,)) array([ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2.])
fromfunction函式的第一個引數為計算每個陣列元素的函式,第二個引數為陣列的大小(shape),因為它支援多維陣列,所以第二個引數必須是一個序列,本例中用(10,)建立一個10元素的一維陣列。
下面的例子建立一個二維陣列表示九九乘法表,輸出的陣列a中的每個元素a[i, j]都等於func2(i, j):
>>> def func2(i, j): ... return (i+1) * (j+1) ... >>> a = np.fromfunction(func2, (9,9)) >>> a array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.], [ 2., 4., 6., 8., 10., 12., 14., 16., 18.], [ 3., 6., 9., 12., 15., 18., 21., 24., 27.], [ 4., 8., 12., 16., 20., 24., 28., 32., 36.], [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], [ 6., 12., 18., 24., 30., 36., 42., 48., 54.], [ 7., 14., 21., 28., 35., 42., 49., 56., 63.], [ 8., 16., 24., 32., 40., 48., 56., 64., 72.], [ 9., 18., 27., 36., 45., 54., 63., 72., 81.]])
Creating record arrays(numpy.rec)
Creating character arrays (numpy.char)
Numerical ranges
arange([start,] stop[, step,][, dtype]) | Return evenly spaced values within a given interval. |
linspace(start, stop[, num, endpoint, ...]) | Return evenly spaced numbers over a specified interval. |
logspace(start, stop[, num, endpoint, base, ...]) | Return numbers spaced evenly on a log scale. |
meshgrid(*xi, **kwargs) | Return coordinate matrices from coordinate vectors. |
mgrid | nd_grid instance which returns a dense multi-dimensional “meshgrid”. |
ogrid | nd_grid instance which returns an open multi-dimensional “meshgrid”. |
arange函式
類似於python的range函式,通過指定開始值、終值和步長來建立一維陣列,注意陣列不包括終值:
>>> np.arange(0,1,0.1)
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
Note:當arange使用浮點數引數時,由於有限的浮點數精度,通常無法預測獲得的元素個數。因此,最好使用函式linspace去接收我們想要的元素個數來代替用range來指定步長。
linspace函式
通過指定開始值、終值和元素個數來建立一維陣列,可以通過endpoint關鍵字指定是否包括終值,預設設定是包括終值:
>>> np.linspace(0,1,12)
array([ 0. , 0.09090909, 0.18181818, 0.27272727, 0.36363636,
0.45454545, 0.54545455, 0.63636364, 0.72727273, 0.81818182,
0.90909091, 1. ])
linspace(start, end, num): 如linspace(0,1,11)結果為[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1];linspace()是要包括終值的
logspace函式
和linspace類似,不過它建立等比數列,下面的例子產生1(10^0)到100(10^2)、有20個元素的等比數列:
>>> np.logspace(0, 2, 20) array([ 1. , 1.27427499, 1.62377674, 2.06913808, 2.6366509 , 3.35981829, 4.2813324 , 5.45559478, 6.95192796, 8.8586679 , 11.28837892, 14.38449888, 18.32980711, 23.35721469, 29.76351442, 37.92690191, 48.32930239, 61.58482111, 78.47599704, 100. ])
meshgrid
有時候需要在二維平面中生成一個網格,這時候可以使用 meshgrid 來完成這樣的工作。
>>> nx, ny = (3, 2)
>>> x = np.linspace(0, 1, nx)
>>> y = np.linspace(0, 1, ny)
>>> xv, yv = meshgrid(x, y)
>>> xv
array([[ 0. , 0.5, 1. ],
[ 0. , 0.5, 1. ]])
>>> yv
array([[ 0., 0., 0.],
[ 1., 1., 1.]])
meshgrid返回值x 對應網格的第一維,y 對應網格的第二維。
meshgrid返回的x, y 中有很多冗餘的元素,這裡提供了一個 sparse 的選項,在這個選項下,x, y 變成了單一的行向量和列向量。
meshgrid 可以設定軸排列的先後順序:
預設為 indexing='xy' 即笛卡爾座標,對於2維陣列,返回行向量 x 和列向量 y
或者使用 indexing='ij' 即矩陣座標,對於2維陣列,返回列向量 x 和行向量 y。
Matlab中meshgrid 的用法
meshgrid(-1:.5:1, -1:.5:1)
Numpy的 meshgrid 並不支援這樣的用法,但我們可以使用 ogrid / mgrid 來實現類似這樣的用法。
ogrid:快速產生廣播運算陣列的ogrid物件
由於這種廣播計算很常用,因此NumPy提供了快速產生能進行廣播運算的陣列的ogrid物件。
>>> x,y = np.ogrid[:5,:5] >>> x array([[0], [1], [2], [3], [4]]) >>> y array([[0, 1, 2, 3, 4]])
ogrid是一個很有趣的物件,它和多維陣列一樣,用切片元組作為下標,返回的是一組可以用來廣播計算的陣列。其切片下標有兩種形式:
開始值:結束值:步長,和“np.arange(開始值, 結束值, 步長)”類似
開始值:結束值:長度j,當第三個引數為虛數時,它表示所返回的陣列的長度,和“np.linspace(開始值, 結束值, 長度)”類似:
>>> x, y = np.ogrid[:1:4j, :1:3j] >>> x array([[ 0. ], [ 0.33333333], [ 0.66666667], [ 1. ]]) >>> y array([[ 0. , 0.5, 1. ]])
利用ogrid的返回值,我們能很容易計算二元函式在等間距網格上的值。
用ogird產生二維座標網格,使用Mayavi的mlab模組快速繪製3D曲面[]
使用ix_()構成網格上點的函式值
如果已經有了多個表示不同軸上的取值的一維陣列。想計算出它們所構成的網格上的每點的函式值,可以使用ix_():
>>> x = np.array([0, 1, 4, 10]) >>> y = np.array([2, 3, 8]) >>> gy, gx = np.ix_(y, x) >>> gx array([[ 0, 1, 4, 10]]) >>> gy array([[2], [3], [8]]) >>> gx+gy # 廣播運算 array([[ 2, 3, 6, 12], [ 3, 4, 7, 13], [ 8, 9, 12, 18]])
在上面的例子中,通過ix_()將陣列x和y轉換成能進行廣播運算的二維陣列。注意陣列y對應廣播運算結果中的第0軸,而陣列x與第1軸對應。
mgrid
mgrid物件的用法和ogrid物件類似,但是它所返回的是進行廣播之後的陣列。np.ogrid[:5,:5]
Out[3]:
[array([[0],
[1],
[2],
[3],
[4]]), array([[0, 1, 2, 3, 4]])]
np.mgrid[:5,:5]
Out[2]:
array([[[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 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]]])
不同grid函式之間的區別和聯絡
ogrid 相當於 meshgrid(indexing='ij', sparse=True)mgrid 相當於 meshgrid(indexing='ij', sparse=False)
lz測試了一下,mgrid的確是用於多維情況,不能繪製一維的多維顯示
如meshgrid可以利用linspace函式繪製x=0固定值時的一維高斯分佈(這時meshgrid中的sparse不能為True)
x, y = np.meshgrid(np.linspace(0, 0, 400), np.linspace(-3, 3, 400)) ax.plot_surface(x, y, rv.pdf(np.dstack((x, y))), rstride=1, cstride=1)但是mgrid要建立x,y後修改x為固定值
x, y = np.mgrid[-3:3:.15, -3:3:.15] x = np.zeros_like(x) ax.plot_surface(x, y, rv.pdf(np.dstack((x, y))), rstride=1, cstride=1)[生成陣列的函式]
[NumPy mgrid vs. meshgrid]
Building matrices
diag(v[, k]) | Extract a diagonal or construct a diagonal array. |
Create a two-dimensional array with the flattened input as a diagonal. | |
tri(N[, M, k, dtype]) | An array with ones at and below the given diagonal and zeros elsewhere. |
tril(m[, k]) | Lower triangle of an array. |
triu(m[, k]) | Upper triangle of an array. |
vander(x[, N, increasing]) | Generate a Vandermonde matrix. |
The Matrix class
mat(data[, dtype]) | Interpret the input as a matrix. |
bmat(obj[, ldict, gdict]) | Build a matrix object from a string, nested sequence, or array. |
ref: Array creation routines*