NumPy數組操作

NumPy - 數組操作

NumPy包中有幾個例程用於處理ndarray對象中的元素。 它們可以分爲以下類型:

修改形狀

序號

形狀及描述

1.

reshape 不改變數據的條件下修改形狀

2.

flat 數組上的一維迭代器

3.

flatten 返回摺疊爲一維的數組副本

4.

ravel 返回連續的展開數組

numpy.reshape

這個函數在不改變數據的條件下修改形狀,它接受如下參數:

numpy.reshape(arr, newshape, order')

其中:

  • arr:要修改形狀的數組
  • newshape:整數或者整數數組,新的形狀應當兼容原有形狀
  • order'C'爲 C 風格順序,'F'爲 F 風格順序,'A'爲保留原順序。

例子

import numpy as np
a = np.arange(8)
print '原始數組:'
print a
print '\n'

b = a.reshape(4,2)
print '修改後的數組:'
print b

輸出如下:

原始數組:
[0 1 2 3 4 5 6 7]

修改後的數組:
[[0 1]
 [2 3]
 [4 5]
 [6 7]]

numpy.ndarray.flat

該函數返回數組上的一維迭代器,行爲類似 Python 內建的迭代器。

例子

import numpy as np
a = np.arange(8).reshape(2,4)
print '原始數組:'
print a
print '\n'

print '調用 flat 函數之後:'
# 返回展開數組中的下標的對應元素
print a.flat[5]

輸出如下:

原始數組:
[[0 1 2 3]
 [4 5 6 7]]

調用 flat 函數之後:
5

numpy.ndarray.flatten

該函數返回摺疊爲一維的數組副本,函數接受下列參數:

ndarray.flatten(order)

其中:

  • order'C' — 按行,'F' — 按列,'A' — 原順序,'k' — 元素在內存中的出現順序。

例子

import numpy as np
a = np.arange(8).reshape(2,4)

print '原數組:'
print a
print '\n'  
# default is column-major

print '展開的數組:'
print a.flatten()
print '\n'  

print '以 F 風格順序展開的數組:'
print a.flatten(order = 'F')

輸出如下:

原數組:
[[0 1 2 3]
 [4 5 6 7]]

展開的數組:
[0 1 2 3 4 5 6 7]

以 F 風格順序展開的數組:
[0 4 1 5 2 6 3 7]

numpy.ravel

這個函數返回展開的一維數組,並且按需生成副本。返回的數組和輸入數組擁有相同數據類型。這個函數接受兩個參數。

numpy.ravel(a, order)

構造器接受下列參數:

  • order'C' — 按行,'F' — 按列,'A' — 原順序,'k' — 元素在內存中的出現順序。

例子

import numpy as np
a = np.arange(8).reshape(2,4)

print '原數組:'
print a
print '\n'  

print '調用 ravel 函數之後:'
print a.ravel()  
print '\n'

print '以 F 風格順序調用 ravel 函數之後:'
print a.ravel(order = 'F')
原數組:
[[0 1 2 3]
 [4 5 6 7]]

調用 ravel 函數之後:
[0 1 2 3 4 5 6 7]

以 F 風格順序調用 ravel 函數之後:
[0 4 1 5 2 6 3 7]

翻轉操作

序號

操作及描述

1.

transpose 翻轉數組的維度

2.

ndarray.Tself.transpose()相同

3.

rollaxis 向後滾動指定的軸

4.

swapaxes 互換數組的兩個軸

numpy.transpose

這個函數翻轉給定數組的維度。如果可能的話它會返回一個視圖。函數接受下列參數:

numpy.transpose(arr, axes)

其中:

  • arr:要轉置的數組
  • axes:整數的列表,對應維度,通常所有維度都會翻轉。

例子

import numpy as np
a = np.arange(12).reshape(3,4)

print '原數組:'
print a  
print '\n'

print '轉置數組:'
print np.transpose(a)

輸出如下:

原數組:
[[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]]

轉置數組:
[[ 0 4 8]
 [ 1 5 9]
 [ 2 6 10]
 [ 3 7 11]]

numpy.ndarray.T

該函數屬於ndarray類,行爲類似於numpy.transpose

例子

import numpy as np
a = np.arange(12).reshape(3,4)

print '原數組:'
print a
print '\n'  

print '轉置數組:'
print a.T

輸出如下:

原數組:
[[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]]

轉置數組:
[[ 0 4 8]
 [ 1 5 9]
 [ 2 6 10]
 [ 3 7 11]]

numpy.rollaxis

該函數向後滾動特定的軸,直到一個特定位置。這個函數接受三個參數:

numpy.rollaxis(arr, axis, start)

其中:

  • arr:輸入數組
  • axis:要向後滾動的軸,其它軸的相對位置不會改變
  • start:默認爲零,表示完整的滾動。會滾動到特定位置。

例子

# 創建了三維的 ndarray
import numpy as np
a = np.arange(8).reshape(2,2,2)

print '原數組:'
print a
print '\n'
# 將軸 2 滾動到軸 0(寬度到深度)

print '調用 rollaxis 函數:'
print np.rollaxis(a,2)  
# 將軸 0 滾動到軸 1:(寬度到高度)
print '\n'

print '調用 rollaxis 函數:'
print np.rollaxis(a,2,1)

輸出如下:

原數組:
[[[0 1]
 [2 3]]
 [[4 5]
 [6 7]]]

調用 rollaxis 函數:
[[[0 2]
 [4 6]]
 [[1 3]
 [5 7]]]

調用 rollaxis 函數:
[[[0 2]
 [1 3]]
 [[4 6]
 [5 7]]]

numpy.swapaxes

該函數交換數組的兩個軸。對於 1.10 之前的 NumPy 版本,會返回交換後數組的試圖。這個函數接受下列參數:

numpy.swapaxes(arr, axis1, axis2)
  • arr:要交換其軸的輸入數組
  • axis1:對應第一個軸的整數
  • axis2:對應第二個軸的整數
# 創建了三維的 ndarray
import numpy as np
a = np.arange(8).reshape(2,2,2)

print '原數組:'
print a
print '\n'  
# 現在交換軸 0(深度方向)到軸 2(寬度方向)

print '調用 swapaxes 函數後的數組:'
print np.swapaxes(a, 2, 0)

輸出如下:

原數組:
[[[0 1]
 [2 3]]

 [[4 5]
  [6 7]]]

調用 swapaxes 函數後的數組:
[[[0 4]
 [2 6]]

 [[1 5]
  [3 7]]]

修改維度

序號

維度和描述

1.

broadcast 產生模仿廣播的對象

2.

broadcast_to 將數組廣播到新形狀

3.

expand_dims 擴展數組的形狀

4.

squeeze 從數組的形狀中刪除單維條目

broadcast

如前所述,NumPy 已經內置了對廣播的支持。 此功能模仿廣播機制。 它返回一個對象,該對象封裝了將一個數組廣播到另一個數組的結果。

該函數使用兩個數組作爲輸入參數。 下面的例子說明了它的用法。

import numpy as np
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])  

# 對 y 廣播 x
b = np.broadcast(x,y)  
# 它擁有 iterator 屬性,基於自身組件的迭代器元組

print '對 y 廣播 x:'
r,c = b.iters
print r.next(), c.next()
print r.next(), c.next()
print '\n'  
# shape 屬性返回廣播對象的形狀

print '廣播對象的形狀:'
print b.shape
print '\n'  
# 手動使用 broadcast 將 x 與 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape)

print '手動使用 broadcast 將 x 與 y 相加:'
print c.shape
print '\n'  
c.flat = [u + v for (u,v) in b]

print '調用 flat 函數:'
print c
print '\n'  
# 獲得了和 NumPy 內建的廣播支持相同的結果

print 'x 與 y 的和:'
print x + y

輸出如下:

對 y 廣播 x:
1 4
1 5

廣播對象的形狀:
(3, 3)

手動使用 broadcast 將 x 與 y 相加:
(3, 3)

調用 flat 函數:
[[ 5. 6. 7.]
 [ 6. 7. 8.]
 [ 7. 8. 9.]]

x 與 y 的和:
[[5 6 7]
 [6 7 8]
 [7 8 9]]

numpy.broadcast_to

此函數將數組廣播到新形狀。 它在原始數組上返回只讀視圖。 它通常不連續。 如果新形狀不符合 NumPy 的廣播規則,該函數可能會拋出ValueError

注意 - 此功能可用於 1.10.0 及以後的版本。

該函數接受以下參數。

numpy.broadcast_to(array, shape, subok)

例子

import numpy as np
a = np.arange(4).reshape(1,4)

print '原數組:'
print a
print '\n'  

print '調用 broadcast_to 函數之後:'
print np.broadcast_to(a,(4,4))

輸出如下:

[[0  1  2  3]
 [0  1  2  3]
 [0  1  2  3]
 [0  1  2  3]]

numpy.expand_dims

函數通過在指定位置插入新的軸來擴展數組形狀。該函數需要兩個參數:

numpy.expand_dims(arr, axis)

其中:

  • arr:輸入數組
  • axis:新軸插入的位置

例子

import numpy as np
x = np.array(([1,2],[3,4]))

print '數組 x:'
print x
print '\n'  
y = np.expand_dims(x, axis = 0)

print '數組 y:'
print y
print '\n'

print '數組 x 和 y 的形狀:'
print x.shape, y.shape
print '\n'  
# 在位置 1 插入軸
y = np.expand_dims(x, axis = 1)

print '在位置 1 插入軸之後的數組 y:'
print y
print '\n'  

print 'x.ndim 和 y.ndim:'
print x.ndim,y.ndim
print '\n'  

print 'x.shape 和 y.shape:'
print x.shape, y.shape

輸出如下:

數組 x:
[[1 2]
 [3 4]]

數組 y:
[[[1 2]
 [3 4]]]

數組 x 和 y 的形狀:
(2, 2) (1, 2, 2)

在位置 1 插入軸之後的數組 y:
[[[1 2]]
 [[3 4]]]

x.shape 和 y.shape:
2 3

x.shape and y.shape:
(2, 2) (2, 1, 2)

numpy.squeeze

函數從給定數組的形狀中刪除一維條目。 此函數需要兩個參數。

numpy.squeeze(arr, axis)

其中:

  • arr:輸入數組
  • axis:整數或整數元組,用於選擇形狀中單一維度條目的子集

例子

import numpy as np  
x = np.arange(9).reshape(1,3,3)

print '數組 x:'
print x
print '\n'  
y = np.squeeze(x)

print '數組 y:'
print y
print '\n'  

print '數組 x 和 y 的形狀:'
print x.shape, y.shape

輸出如下:

數組 x:
[[[0 1 2]
 [3 4 5]
 [6 7 8]]]

數組 y:
[[0 1 2]
 [3 4 5]
 [6 7 8]]

數組 x 和 y 的形狀:
(1, 3, 3) (3, 3)

數組的連接

序號

數組及描述

1.

concatenate 沿着現存的軸連接數據序列

2.

stack 沿着新軸連接數組序列

3.

hstack 水平堆疊序列中的數組(列方向)

4.

vstack 豎直堆疊序列中的數組(行方向)

numpy.concatenate

數組的連接是指連接。 此函數用於沿指定軸連接相同形狀的兩個或多個數組。 該函數接受以下參數。

numpy.concatenate((a1, a2, ...), axis)

其中:

  • a1, a2, ...:相同類型的數組序列
  • axis:沿着它連接數組的軸,默認爲 0

例子

import numpy as np
a = np.array([[1,2],[3,4]])

print '第一個數組:'
print a
print '\n'  
b = np.array([[5,6],[7,8]])

print '第二個數組:'
print b
print '\n'  
# 兩個數組的維度相同

print '沿軸 0 連接兩個數組:'
print np.concatenate((a,b))
print '\n'  

print '沿軸 1 連接兩個數組:'
print np.concatenate((a,b),axis = 1)

輸出如下:

第一個數組:
[[1 2]
 [3 4]]

第二個數組:
[[5 6]
 [7 8]]

沿軸 0 連接兩個數組:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

沿軸 1 連接兩個數組:
[[1 2 5 6]
 [3 4 7 8]]

numpy.stack

此函數沿新軸連接數組序列。 此功能添加自 NumPy 版本 1.10.0。 需要提供以下參數。

numpy.stack(arrays, axis)

其中:

  • arrays:相同形狀的數組序列
  • axis:返回數組中的軸,輸入數組沿着它來堆疊
import numpy as np
a = np.array([[1,2],[3,4]])

print '第一個數組:'
print a
print '\n'
b = np.array([[5,6],[7,8]])

print '第二個數組:'
print b
print '\n'  

print '沿軸 0 堆疊兩個數組:'
print np.stack((a,b),0)
print '\n'  

print '沿軸 1 堆疊兩個數組:'
print np.stack((a,b),1)

輸出如下:

第一個數組:
[[1 2]
 [3 4]]

第二個數組:
[[5 6]
 [7 8]]

沿軸 0 堆疊兩個數組:
[[[1 2]
 [3 4]]
 [[5 6]
 [7 8]]]

沿軸 1 堆疊兩個數組:
[[[1 2]
 [5 6]]
 [[3 4]
 [7 8]]]

numpy.hstack

numpy.stack函數的變體,通過堆疊來生成水平的單個數組。

例子

import numpy as np
a = np.array([[1,2],[3,4]])

print '第一個數組:'
print a
print '\n'  
b = np.array([[5,6],[7,8]])

print '第二個數組:'
print b
print '\n'  

print '水平堆疊:'
c = np.hstack((a,b))
print c
print '\n'

輸出如下:

第一個數組:
[[1 2]
 [3 4]]

第二個數組:
[[5 6]
 [7 8]]

水平堆疊:
[[1 2 5 6]
 [3 4 7 8]]

numpy.vstack

numpy.stack函數的變體,通過堆疊來生成豎直的單個數組。

import numpy as np
a = np.array([[1,2],[3,4]])

print '第一個數組:'
print a
print '\n'  
b = np.array([[5,6],[7,8]])

print '第二個數組:'
print b
print '\n'

print '豎直堆疊:'
c = np.vstack((a,b))
print c

輸出如下:

第一個數組:
[[1 2]
 [3 4]]

第二個數組:
[[5 6]
 [7 8]]

豎直堆疊:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

數組分割

序號

數組及操作

1.

split 將一個數組分割爲多個子數組

2.

hsplit 將一個數組水平分割爲多個子數組(按列)

3.

vsplit 將一個數組豎直分割爲多個子數組(按行)

numpy.split

該函數沿特定的軸將數組分割爲子數組。函數接受三個參數:

numpy.split(ary, indices_or_sections, axis)

其中:

  • ary:被分割的輸入數組
  • indices_or_sections:可以是整數,表明要從輸入數組創建的,等大小的子數組的數量。 如果此參數是一維數組,則其元素表明要創建新子數組的點。
  • axis:默認爲 0

例子

import numpy as np
a = np.arange(9)

print '第一個數組:'
print a
print '\n'  

print '將數組分爲三個大小相等的子數組:'
b = np.split(a,3)
print b
print '\n'  

print '將數組在一維數組中表明的位置分割:'
b = np.split(a,[4,7])
print b

輸出如下:

第一個數組:
[0 1 2 3 4 5 6 7 8]

將數組分爲三個大小相等的子數組:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

將數組在一維數組中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

numpy.hsplit

numpy.hsplitsplit()函數的特例,其中軸爲 1 表示水平分割,無論輸入數組的維度是什麼。

import numpy as np
a = np.arange(16).reshape(4,4)

print '第一個數組:'
print a
print '\n'  

print '水平分割:'
b = np.hsplit(a,2)
print b
print '\n'

輸出:

第一個數組:
[[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]
 [12 13 14 15]]

水平分割:                                                         
[array([[ 0,  1],                                                             
       [ 4,  5],                                                              
       [ 8,  9],                                                              
       [12, 13]]), array([[ 2,  3],                                           
       [ 6,  7],                                                              
       [10, 11],                                                              
       [14, 15]])]

numpy.vsplit

numpy.vsplitsplit()函數的特例,其中軸爲 0 表示豎直分割,無論輸入數組的維度是什麼。下面的例子使之更清楚。

import numpy as np
a = np.arange(16).reshape(4,4)

print '第一個數組:'
print a
print '\n'

print '豎直分割:'
b = np.vsplit(a,2)
print b

輸出如下:

第一個數組:
[[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]
 [12 13 14 15]]

豎直分割:                                                           
[array([[0, 1, 2, 3],                                                         
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],                               
       [12, 13, 14, 15]])]

添加/刪除元素

序號

元素及描述

1.

resize 返回指定形狀的新數組

2.

append 將值添加到數組末尾

3.

insert 沿指定軸將值插入到指定下標之前

4.

delete 返回刪掉某個軸的子數組的新數組

5.

unique 尋找數組內的唯一元素

numpy.resize

此函數返回指定大小的新數組。 如果新大小大於原始大小,則包含原始數組中的元素的重複副本。 該函數接受以下參數。

numpy.resize(arr, shape)

其中:

  • arr:要修改大小的輸入數組
  • shape:返回數組的新形狀

例子

import numpy as np
a = np.array([[1,2,3],[4,5,6]])

print '第一個數組:'
print a
print '\n'

print '第一個數組的形狀:'
print a.shape
print '\n'  
b = np.resize(a, (3,2))

print '第二個數組:'
print b
print '\n'  

print '第二個數組的形狀:'
print b.shape
print '\n'  
# 要注意 a 的第一行在 b 中重複出現,因爲尺寸變大了

print '修改第二個數組的大小:'
b = np.resize(a,(3,3))
print b

輸出如下:

第一個數組:
[[1 2 3]
 [4 5 6]]

第一個數組的形狀:
(2, 3)

第二個數組:
[[1 2]
 [3 4]
 [5 6]]

第二個數組的形狀:
(3, 2)

修改第二個數組的大小:
[[1 2 3]
 [4 5 6]
 [1 2 3]]

numpy.append

此函數在輸入數組的末尾添加值。 附加操作不是原地的,而是分配新的數組。 此外,輸入數組的維度必須匹配否則將生成ValueError

函數接受下列函數:

numpy.append(arr, values, axis)

其中:

  • arr:輸入數組
  • values:要向arr添加的值,比如和arr形狀相同(除了要添加的軸)
  • axis:沿着它完成操作的軸。如果沒有提供,兩個參數都會被展開。

例子

import numpy as np
a = np.array([[1,2,3],[4,5,6]])

print '第一個數組:'
print a
print '\n'  

print '向數組添加元素:'
print np.append(a, [7,8,9])
print '\n'  

print '沿軸 0 添加元素:'
print np.append(a, [[7,8,9]],axis = 0)
print '\n'  

print '沿軸 1 添加元素:'
print np.append(a, [[5,5,5],[7,8,9]],axis = 1)

輸出如下:

第一個數組:
[[1 2 3]
 [4 5 6]]

向數組添加元素:
[1 2 3 4 5 6 7 8 9]

沿軸 0 添加元素:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

沿軸 1 添加元素:
[[1 2 3 5 5 5]
 [4 5 6 7 8 9]]

numpy.insert

此函數在給定索引之前,沿給定軸在輸入數組中插入值。 如果值的類型轉換爲要插入,則它與輸入數組不同。 插入沒有原地的,函數會返回一個新數組。 此外,如果未提供軸,則輸入數組會被展開。

insert()函數接受以下參數:

numpy.insert(arr, obj, values, axis)

其中:

  • arr:輸入數組
  • obj:在其之前插入值的索引
  • values:要插入的值
  • axis:沿着它插入的軸,如果未提供,則輸入數組會被展開

例子

import numpy as np
a = np.array([[1,2],[3,4],[5,6]])

print '第一個數組:'
print a
print '\n'  

print '未傳遞 Axis 參數。 在插入之前輸入數組會被展開。'
print np.insert(a,3,[11,12])
print '\n'  
print '傳遞了 Axis 參數。 會廣播值數組來配輸入數組。'

print '沿軸 0 廣播:'
print np.insert(a,1,[11],axis = 0)
print '\n'  

print '沿軸 1 廣播:'
print np.insert(a,1,11,axis = 1)

numpy.delete

此函數返回從輸入數組中刪除指定子數組的新數組。 與insert()函數的情況一樣,如果未提供軸參數,則輸入數組將展開。 該函數接受以下參數:

Numpy.delete(arr, obj, axis)

其中:

  • arr:輸入數組
  • obj:可以被切片,整數或者整數數組,表明要從輸入數組刪除的子數組
  • axis:沿着它刪除給定子數組的軸,如果未提供,則輸入數組會被展開

例子

import numpy as np
a = np.arange(12).reshape(3,4)

print '第一個數組:'
print a
print '\n'  

print '未傳遞 Axis 參數。 在插入之前輸入數組會被展開。'
print np.delete(a,5)
print '\n'  

print '刪除第二列:'  
print np.delete(a,1,axis = 1)
print '\n'  

print '包含從數組中刪除的替代值的切片:'
a = np.array([1,2,3,4,5,6,7,8,9,10])
print np.delete(a, np.s_[::2])

輸出如下:

第一個數組:
[[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]]

未傳遞 Axis 參數。 在插入之前輸入數組會被展開。
[ 0 1 2 3 4 6 7 8 9 10 11]

刪除第二列:
[[ 0 2 3]
 [ 4 6 7]
 [ 8 10 11]]

包含從數組中刪除的替代值的切片:
[ 2 4 6 8 10]

numpy.unique

此函數返回輸入數組中的去重元素數組。 該函數能夠返回一個元組,包含去重數組和相關索引的數組。 索引的性質取決於函數調用中返回參數的類型。

numpy.unique(arr, return_index, return_inverse, return_counts)

其中:

  • arr:輸入數組,如果不是一維數組則會展開
  • return_index:如果爲true,返回輸入數組中的元素下標
  • return_inverse:如果爲true,返回去重數組的下標,它可以用於重構輸入數組
  • return_counts:如果爲true,返回去重數組中的元素在原數組中的出現次數

例子

import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])

print '第一個數組:'
print a
print '\n'  

print '第一個數組的去重值:'
u = np.unique(a)
print u
print '\n'  

print '去重數組的索引數組:'
u,indices = np.unique(a, return_index = True)
print indices
print '\n'  

print '我們可以看到每個和原數組下標對應的數值:'
print a
print '\n'  

print '去重數組的下標:'
u,indices = np.unique(a,return_inverse = True)
print u
print '\n'

print '下標爲:'
print indices
print '\n'  

print '使用下標重構原數組:'
print u[indices]
print '\n'  

print '返回去重元素的重複數量:'
u,indices = np.unique(a,return_counts = True)
print u
print indices

輸出如下:

第一個數組:
[5 2 6 2 7 5 6 8 2 9]

第一個數組的去重值:
[2 5 6 7 8 9]

去重數組的索引數組:
[1 0 2 4 7 9]

我們可以看到每個和原數組下標對應的數值:
[5 2 6 2 7 5 6 8 2 9]

去重數組的下標:
[2 5 6 7 8 9]

下標爲:
[1 0 2 0 3 1 2 4 0 5]

使用下標重構原數組:
[5 2 6 2 7 5 6 8 2 9]

返回唯一元素的重複數量:
[2 5 6 7 8 9]
 [3 2 2 1 1 1]