【3】数据分析-1-数据的处理--numpy--2--数组基本操作

创建、索引、组合、分割、复制、遍历、转换、序列化

一.创建数组

以list或tuple变量为参数产生一维数组:

>>> from numpy import *
>>> a = array( [2,3,4] )
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int32')
>>> b = array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')

以list或tuple变量为元素产生二维数组:

>>> print np.array([[1,2],[3,4]])
[[1 2]
 [3 4]]

生成数组的时候,可以指定数据类型,例如numpy.int32, numpy.int16, and numpy.float64等。the dtype of the created array is float64

>>> print np.array((1.2,2,3,4), dtype=np.int32)
[1 2 3 4]

使用numpy.arange方法

>>> print np.arange(15)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
>>> print type(np.arange(15))
<type 'numpy.ndarray'>
>>> print np.arange(15).reshape(3,5)
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
>>> print type(np.arange(15).reshape(3,5))
<type 'numpy.ndarray'>

np.zeros 或 np.ones  0或都是1,或者任意数的数组

    >>> np.zeros( (3,4) )
    array([[0.,  0.,  0.,  0.],
                 [0.,  0.,  0.,  0.],
                 [0.,  0.,  0.,  0.]])
    >>> np.ones( (2,3,4), dtype=int16 )                # dtype can also be specified
    array([[[ 1, 1, 1, 1],
                    [ 1, 1, 1, 1],
                    [ 1, 1, 1, 1]],
                 [[ 1, 1, 1, 1],
                    [ 1, 1, 1, 1],
                    [ 1, 1, 1, 1]]], dtype=int16)
    >>> np.empty( (2,3) )
    array([[  3.73603959e-262,   6.02658058e-154,   6.55490914e-260],
                 [  5.30498948e-313,   3.14673309e-307,   1.00000000e+000]])

2.使用NumPy中函数创建ndarray数组,如:arange, ones, zeros等

np.ones_like(a)

根据数组a的形状生成一个全1数组

np.zeros_like(a)

根据数组a的形状生成一个全0数组

np.full_like(a,val)

根据数组a的形状生成一个数组,每个元素值都是val

3.使用NumPy中其他函数创建ndarray数组

np.linspace()

根据起止数据等间距地填充数据,形成数组

np.concatenate()

将两个或多个数组合并成一个新的数组

4.ndarray数组的维度变换

.reshape(shape)  不改变原数组元素
.resize(shape)      改变原数组元素
.swapaxes(ax1,ax2)

将数组n个维度中两个维度进行调换.flatten()

对数组进行降维,返回折叠后的一维数组,原数组不变

  1. ndarray数组的类型变换

    new_a = a.astype(new_type)

astype()方法一定会创建新的数组(原始数据的一个拷贝),即使两个类型一致

    >>> from numpy import *
    >>> import numpy as np
    >>> a= np.ones((2,3,4),dtype=np.int)
    >>> a
    array([[[1, 1, 1, 1],
     [1, 1, 1, 1],
     [1, 1, 1, 1]],

    [[1, 1, 1, 1],
     [1, 1, 1, 1],
     [1, 1, 1, 1]]])
    >>> b=a.astype(np.float)
    >>> b
    array([[[ 1., 1., 1., 1.],
     [ 1., 1., 1., 1.],
     [ 1., 1., 1., 1.]],


    [[ 1., 1., 1., 1.],
     [ 1., 1., 1., 1.],
     [ 1., 1., 1., 1.]]])

7.ndarray数组向列表的转换

ls = a.tolist()

生成排序的数

>>> arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> arange( 0, 2, 0.3 ) # it accepts float arguments
array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])

>>> linspace( 0, 2, 9 ) # 9 numbers from 0 to 2
array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
>>> x = linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points
>>> f = sin(x)

二、索引与切片

一维数组

>>> a = arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000    
# equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
>>> a
array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   729])
>>> a[ : :-1]                                 # reversed a
array([  729,   512,   343,   216,   125, -1000,    27, -1000,     1, -1000])
>>> for i in a:
...         print i**(1/3.),
...
nan 1.0 nan 3.0 nan 5.0 6.0 7.0 8.0 9.0

二维数组

>>> def f(x,y):
...         return 10*x+y
...
>>> b = fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0,  1,  2,  3],
             [10, 11, 12, 13],
             [20, 21, 22, 23],
             [30, 31, 32, 33],
             [40, 41, 42, 43]])
>>> b[2,3]
23
>>> b[0:5, 1]                       # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1]                        # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ]                      # each column in the second and third row of b
array([[10, 11, 12, 13],
             [20, 21, 22, 23]])


>>> b[-1]                        # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])

.的用处

>>> c = array( [ [[  0,  1,  2],      # a 3D array (two stacked 2D arrays)
...               [ 10, 12, 13]],
...
...              [[100,101,102],
...               [110,112,113]] ] )
>>> c.shape
(2, 2, 3)
>>> c[1,...]                                   # same as c[1,:,:] or c[1]
array([[100, 101, 102],
             [110, 112, 113]])
>>> c[...,2]                                   # same as c[:,:,2]
array([[  2,  13],
             [102, 113]])

输出一维数据

>>> for row in b:
...         print row
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]

输出所有元素

>>> for element in b.flat:
...         print element,
...
0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43

三、数组的组合(函数)

#创建两个测试数组

a = np.arange(9).reshape(3,3)    
''''' 
 array([[0, 1, 2],   
           [3, 4, 5],   
           [6, 7, 8]])   
'''  
b = 2 * a  
''''' 
array([[ 0, 2, 4],   
       [ 6, 8, 10],   
       [12, 14, 16]])   

''' 

#水平组合

np.hstack((a, b))   
''''' 
array([[ 0, 1, 2, 0, 2, 4],   
       [ 3, 4, 5, 6, 8, 10],   
       [ 6, 7, 8, 12, 14, 16]])  
'''  

#通过concatenate函数并指定相应的轴 (axis=1 水平,axis=0 垂直)  
con = np.concatenate((a, b), axis=1)  
''''' 
array([[ 0, 1, 2, 0, 2, 4],   
       [ 3, 4, 5, 6, 8, 10],   
       [ 6, 7, 8, 12, 14, 16]])

#垂直组合

np.vstack((a, b))  
''''' 
array([[ 0, 1, 2],   
       [ 3, 4, 5],   
       [ 6, 7, 8],    
       [ 0, 2, 4],   
       [ 6, 8, 10],   
       [12, 14, 16]])   

'''  
#或者使用concatenate   
con = np.concatenate((a, b), axis=0) 

#深度组合 dstack(就是在数组的第三个轴(即深度)上组合,生成一个新的列表数组)

np.dstack((a, b))    
''''' 
array([[[ 0, 0],   
        [ 1, 2],   
        [ 2, 4]],   

       [[ 3, 6],   
        [ 4, 8],   
        [ 5, 10]],   

       [[ 6, 12],   
        [ 7, 14],   
        [ 8, 16]]])   
'''  

#行组合,行组合可将多个一维数组作为新数组的每一行进行组合 #对于2维数组,其作用就像垂直组合一样。

one = np.arange(2)  
''''' 
array([0, 1]) 
'''  

two = one + 2   
''''' 
array([2, 3]) 
'''  

np.row_stack((one, two))  
''''' 

array([[0, 1],   
       [2, 3]])  
'''  

#列组合(对于2维数组,其作用就像水平组合一样。)

np.column_stack((oned, twiceoned))    
''''' 
array([[0, 2],   
       [1, 3]])   
'''

四、数组分割

在NumPy中,分割数组的函数有hsplit、vsplit、dsplit和split。可将数组分割成相同大小的子数组,或指定原数组分割的位置。

#水平分割

a = arange(9).reshape(3,3)   
''''' 
array([[0, 1, 2],   
       [3, 4, 5],   
       [6, 7, 8]])  
'''  

np.hsplit(a, 3)   
''''' 
[array([[0],   
       [3],   
       [6]]),   
 array([[1],   
       [4],   
       [7]]),   
 array([[2],   
       [5],   
       [8]])]  

'''  
#方法二:用split函数并指定轴为1  
np.split(a, 3, axis=1) 

#垂直分割 #垂直分割是沿着垂直的轴切分数组:

np.vsplit(a, 3)    
''''' 
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]  
'''  

#方法二  
#solit函数并指定轴为1  
np.split(a, 3, axis=0)

#面向深度的分割 #dsplit函数使用的是面向深度的分割

c = arange(27).reshape(3, 3, 3)    

''''' 
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]]])   

'''  

np.dsplit(c, 3)   
''''' 
[array([[[ 0],   
        [ 3],   
        [ 6]],   

       [[ 9],   
        [12],   
        [15]],   

       [[18],   
        [21],   
        [24]]]),   
 array([[[ 1],   
        [ 4],   
        [ 7]],   

       [[10],   
        [13],   
        [16]],   

       [[19],   
        [22],   
        [25]]]),   
 array([[[ 2],   
        [ 5],   
        [ 8]],   

       [[11],   
        [14],   
        [17]],   

       [[20],   
        [23],   
        [26]]])]   
''' 

五、判断数组是否共享内存,也是用来直接判断数据是复制的还是镜像的

#方法一:  
a = np.arange(50)  
b = a.reshape((5, 10))  
print (b.base is a)  

#方法二:  
print (np.may_share_memory(a, b))  

#方法三:  
print (b.flags['OWNDATA'])  #False -- apparently this is a view  
e = np.ravel(b[:, 2])  
print (e.flags['OWNDATA'])  #True -- Apparently this is a new numpy object.  

六、数组复制和镜像( view )

1.)完全不复制 ,简单的赋值,而不复制数组对象或它们的数据。

a = np.arange(12)    
b = a      #不创建新对象    
b is a     # a和b是同一个数组对象的两个名字  
#  true  

b.shape = 3,4    #也改变了a的形状   
print a.shape  
''''' 
(3, 4) 
''' 

2.) view的用法 视图方法创造一个新的数组对象指向同一数据。

事实上,没有任何数据类型是固定的,主要取决于如何看待这片数据的内存区域。 在numpy.ndarray.view中,提供对内存区域不同的切割方式,来完成数据类型的转换,而无须要对数据进行额外的copy,来节约内存空间。

c = a.view()    
c is a    
# false  

c.base is a      #c是a持有数据的镜像   
#true  

c.shape = 2,6    # a的形状没变  
print(a.shape)  # (3, 4)   

c[0,4] = 1234        #a的数据改变了  
print  a  
''''' 
array([[   0,    1,    2,    3],   
       [1234,    5,    6,    7],   
       [   8,    9,   10,   11]]) 
'''  

3.)切片数组返回它的一个视图

s = a[ : , 1:3]     # 获得每一行1,2处的元素  
s[:] = 10           # s[:] 是s的镜像。注意区别s=10 and s[:]=10   
print a  
''''' 
array([[   0,   10,   10,    3],   
       [1234,   10,   10,    7],   
       [   8,   10,   10,   11]])   
'''  

4.)深复制,这个复制方法完全复制数组和它的数据。

d = a.copy()       #创建了一个含有新数据的新数组对象  
d is a  
#False  

d.base is a        #d和a现在没有任何关系  
#False    

d[0,0] = 9999  
print a  
''''' 
array([[   0,   10,   10,    3],   
       [1234,   10,   10,    7],   
       [   8,   10,   10,   11]])  
'''

5.)在图像处理中的应用

当需要对输入图像三个通道进行相同的处理时,使用cv2.split和cv2.merge是相当浪费资源的,因为任何一个通道的数据对处理来说都是一样的,我们可以用view来将其转换为一维矩阵后再做处理,这要不需要额外的内存开销和时间开销。

def createFlatView(array):    
    """Return a 1D view of an array of any dimensionality."""    
    flatView = array.view()    
    flatView.shape = array.size    
    return flatView   

六、数组遍历

a = np.arange(9).reshape(3,3)   
for row in a:  
  print row   
''''' 
[0 1 2] 
[3 4 5] 
[6 7 8] 

'''  

#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:  
for element in a.flat:  
  print element  
''''' 
0 1 2 3 4 5 6 7 8 
'''

七、数据类型转换

np.float64(42) # to float64  
#42.0  

np.int8(42.0)  # to int8  
#42  

np.bool(42)   # to bool  
#True    

np.bool(42.0)  # to bool  
#True    

np.float(True)  # to float  
#1.0   


#函数的参数中可以指定参数的类型  
arange(7, dtype=uint16)    
    array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)  

八、 数组序列化和反序列化

序列化是将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。

python 提供pickle, cPickle 对象序列化/反序列化

这里使用numpy 提供的函数

#预定义数据栏位名称和类型    
table = np.loadtxt('example.txt',dtype='names': ('ID', 'Result', 'Type'),\    
    'formats': ('S4', 'f4', 'i2'))    
np.savetxt('somenewfile.txt')#序列化    
#二进制文件加载,保存    
data = np.empty((1000, 1000))    
np.save('test.npy', data)    
np.savez('test.npz', data)#采用压缩    
newdata = np.load('test.npy')  

九、数组中最大值最小值

mat.max(0)#n维数组axis=0维度的最小值,最大值    
mat.min(0)# 

参考资料:

个人公众号,比较懒,很少更新,可以在上面提问题:

更多精彩,请移步公众号阅读:

Sam avatar
About Sam
专注生物信息 专注转化医学