numpy

《Python数据分析基础教程,munpy学习指南(第二版)》:代码
http://www.pudn.com/Download/item/id/2742220.html

numpy 学习指南

http://www.pudn.com/Download/item/id/2742220.html
https://www.jianshu.com/p/04d180d90a3f
https://wizardforcel.gitbooks.io/pandas-cookbook-code-notes/content/2.html


http://pandas.pydata.org

1,测试numpy 和python 自带数组操作时间比较

import numpy as np
import datetime  as datetime
def numpysum(n):
    a = np.arange(n) ** 2
    b = np.arange(n) ** 3 
    c = a + b 
    return c
def pythonsum(n):
    a = list(range(n))
    b = list(range(n))
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] + b[i])
    return c



start = int(round(time.time() * 1000))
c = numpysum(500000)
delta = int(round(time.time() * 1000)) - start 
print("numpysum use " )
print(str(delta))


start = int(round(time.time() * 1000))
c = pythonsum(500000)
delta = int(round(time.time() * 1000)) - start 
print("pysum use " )
print(str(delta))

帮助

np.arange?

NumPy 数组对象

ndarray是一个多维数组对象,该对象由两部分组成, (The N-dimensional array (ndarray))

实际的数据;

描述这些数据的元数据

大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据

一维数组向量:

一个包含5个元素的向量,取值分别为0~4的整数。数组的shape属性返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小

a = np.arange(5)
print(a)
a.dtype
[0 1 2 3 4]
dtype('int64')


a.shape
(5,)

多维数据向量

m = np.array([np.arange(2), np.arange(2)])
m.shape  2 
[[0 1]
 [0 1]]


##3x3维度
np.array([np.arange(3), np.arange(3), np.arange(3)])

选取数组

a[m,n]  m,n 为元素下标
[0,0][0,1]
[1,0][1,1]

numpy 数据类型

bool 用一位存储的布尔类型(值为TRUE或FALSE)
inti 由所在平台决定其精度的整数(一般为int32或int64)
int8 整数,范围为128至127
int16 整数,范围为32 768至32 767
int32 整数,范围为231至231 1
int64 整数,范围为263至263 1
uint8 无符号整数,范围为0至255
uint16 无符号整数,范围为0至65 535
uint32 无符号整数,范围为0至2321
uint64 无符号整数,范围为0至2641
float16 半精度浮点数(16位):其中用1位表示正负号,5位表示指数,10位表示尾数
float32 单精度浮点数(32位):其中用1位表示正负号,8位表示指数,23位表示尾数
float64或float 双精度浮点数(64位):其中用1位表示正负号,11位表示指数,52位表示尾数
complex64 复数,分别用两个32位浮点数表示实部和虚部
complex128或complex 复数,分别用两个64位浮点数表示实部和虚部

数据类型对象:

数据类型对象是numpy.dtype类的实例。如前所述,NumPy数组是有数据类型的,更确切地说,NumPy数组中的每一个元素均为相同的数据类型。数据类型对象可以给出单个数组元素在内存中占用的字节数,即dtype类的itemsize属性. m.dtype.itemsize

字符编码

整数 i
无符号整数 u
单精度浮点数 f
双精度浮点数 d
布尔值 b
复数 D
字符串 S
unicode字符串 U
void (空) V

np.arange(7, dtype='f')

自定义数据类型

In: dtype(float) 
Out: dtype('float64') 

In: dtype('f') 
Out: dtype('float32') 


In: dtype('d') 
Out: dtype('float64') 

创建自定义数据类型

t = np.dtype([('name',str, 40), ('numitems', int), ('price',float)]) 
t['name']

itemz = np.array([('Meaning of life DVD', 42, 3.14), ('Butter', 13, 2.72)], dtype=t)

t = np.dtype([('name', 'S', 40), ('numitems', 'int32'), ('price', 'float32')])   ##这个是正常的
获取帮助 np.dtype?

一维数组的索引和切片

In: a[::-1] 
Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0])    利用负数下标翻转数组

多维数组的切片和索引

b = np.arange(24).reshape(2,3,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]]])

b.shape
(2, 3, 4)

多维数组b中有0~23的整数,共24个元素,是一个2×3×4的三维数组。我们可以形象地把它看做一个两层楼建筑,每层楼有12个房间,并排列成3行4列

或者将其看成是电子表格中工作表(sheet)、行和列的关系

#以用三维坐标来选定任意一个房间,即楼层、行号和列号
b[0,0,0]


#如果我们不关心楼层,也就是说要选取所有楼层的第1行、第1列的房间,那么可以将第1个下标用英文标点的冒号:来代替
b[:, 0,0]

#选取第1层楼的所有房间
b[0, :, :]
多个冒号可以用一个省略号(...)来代替
b[0, ...]

#选取第1层楼、第2排的所有房间
b[0,1]

#数组切片中间隔地选定元素
b[0,1,::2]
#要选取所有楼层的位于第2列的房间,即不指定楼层和行号
b[...,1]
#选取所有位于第2行的房间,而不指定楼层和列号
b[:,1]
#选取第1层楼的所有位于第2列的房间
b[0,:,1]
#要选取第1层楼的最后一列的所有房间
b[0,::-1, -1]

#该数组切片中间隔地选定元素
b[0,::2,-1]

#数组切片中间隔地选定元素
b[0,::2,-1]

#第1层楼和第2层楼的房间交换
b[::-1]

改变数组的维度

#用ravel函数完成展平的操作
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]]])

b.ravel()
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])

#flatten就是展平的意思,与ravel函数的功能相同,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图(view)
b.flatten()

#用元组设置维度
b.shape = (6,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]])

# transpose 在线性代数中,转置矩阵是很常见的操作。对于多维数组
b.transpose()
array([[ 0,  4,  8, 12, 16, 20],
       [ 1,  5,  9, 13, 17, 21],
       [ 2,  6, 10, 14, 18, 22],
       [ 3,  7, 11, 15, 19, 23]])

# resize resize和reshape函数的功能一样,但resize会直接修改所操作的数组
b.resize((2,12)) 

组合数组

水平组合,垂直, 深度组合,列组合,行组合

import numpy as np
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))
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))
np.concatenate((a, b), axis = 0)
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

#深度组合 是将一系列数组沿着纵轴(深度)方向进行层叠组合
举个例子,有若干张二维平面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起

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

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

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

##列组合 column_stack函数对于一维数组将按列方向进行组合
In: oned = arange(2) 
In: oned 
Out: array([0, 1]) 
In: twice_oned = 2 * oned 
In: twice_oned 
Out: array([0, 2]) 
In: column_stack((oned, twice_oned)) 
Out: 
array([[0, 0], 
 [1, 2]]) 

对于二维数组,column_stack与hstack的效果是相同的
In: column_stack((a, b)) 
Out: 
array([[ 0, 1, 2, 0, 2, 4], 
 [ 3, 4, 5, 6, 8,10], 
 [ 6, 7, 8,12,14,16]]) 
In: column_stack((a, b)) == hstack((a, b)) 
Out: 
array([[ True, True, True, True, True, True], 
 [ True, True, True, True, True, True], 
 [ True, True, True, True, True, True]], dtype=bool) 

我们可以用==运算符来比较两个NumPy数组
#行组合 
In: row_stack((oned, twice_oned)) 
Out: 
array([[0, 1], 
 [0, 2]])

对于二维数组,row_stack与vstack的效果是相同的:
In: row_stack((a, b)) 
Out: 
array([[ 0, 1, 2], 
 [ 3, 4, 5], 
 [ 6, 7, 8], 
 [ 0, 2, 4], 
 [ 6, 8,10], 
 [12,14,16]]) 
In: row_stack((a,b)) == vstack((a, b)) 
Out: 
array([[ True, True, True], 
 [ True, True, True], 
 [ True, True, True], 
 [ True, True, True], 
 [ True, True, True], 
 [ True, True, True]], dtype=bool)

数组的分割

NumPy数组可以进行水平、垂直或深度分割,相关的函数有hsplit、vsplit、dsplit和split。我们可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置

##水平分割   把数组沿着水平方向分割为3个相同大小的子数组:
hsplit(a, 3)

##垂直分割


##深度分割

##

数组的属性

除了shape和dtype属性以外,ndarray对象还有很多其他的属

nidm
b.ndim 维度

size属性  给出数组元素的总个数

itemsize属性,给出数组中的元素在内存中所占的字节数

使用tolist函数将NumPy数组转换成Python列表

In: b 
Out: array([ 1.+1.j, 3.+2.j]) 
In: b.tolist() 
Out: [(1+1j), (3+2j)] 

astype函数可以在转换数组时指定数据类型

In: b 
Out: array([ 1.+1.j, 3.+2.j]) 
In: b.astype(int) 
/usr/local/bin/ipython:1: ComplexWarning: Casting complex values to real discards the 
imaginary part 
 #!/usr/bin/python 
Out: array([1, 3]) 

股票实验

原始数据

AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800 
AAPL,31-01-2011, ,335.8,340.04,334.3,339.32,13473000 
AAPL,01-02-2011, ,341.3,345.65,340.98,345.03,15236800 
AAPL,02-02-2011, ,344.45,345.25,343.55,344.32,9242600 
AAPL,03-02-2011, ,343.8,344.24,338.55,343.44,14064100 
AAPL,04-02-2011, ,343.61,346.7,343.51,346.5,11494200 
AAPL,07-02-2011, ,347.89,353.25,347.64,351.88,17322100 
AAPL,08-02-2011, ,353.68,355.52,352.15,355.2,13608500 
AAPL,09-02-2011, ,355.19,359,354.87,358.16,17240800 
AAPL,10-02-2011, ,357.39,360,348,354.54,33162400 
AAPL,11-02-2011, ,354.75,357.8,353.54,356.85,13127500 
AAPL,14-02-2011, ,356.79,359.48,356.71,359.18,11086200 
AAPL,15-02-2011, ,359.19,359.97,357.55,359.9,10149000 
AAPL,16-02-2011, ,360.8,364.9,360.5,363.13,17184100 
AAPL,17-02-2011, ,357.1,360.27,356.52,358.3,18949000 
AAPL,18-02-2011, ,358.21,359.5,349.52,350.56,29144500 
AAPL,22-02-2011, ,342.05,345.4,337.72,338.61,31162200 
AAPL,23-02-2011, ,338.77,344.64,338.61,342.62,23994700 
AAPL,24-02-2011, ,344.02,345.15,338.37,342.88,17853500 
AAPL,25-02-2011, ,345.29,348.43,344.8,348.16,13572000 
AAPL,28-02-2011, ,351.21,355.05,351.12,353.21,14395400 
AAPL,01-03-2011, ,355.47,355.72,347.68,349.31,16290300 
AAPL,02-03-2011, ,349.96,354.35,348.4,352.12,21521000 
AAPL,03-03-2011, ,357.2,359.79,355.92,359.56,17885200 
AAPL,04-03-2011, ,360.07,360.29,357.75,360,16188000 
AAPL,07-03-2011, ,361.11,361.67,351.31,355.36,19504300 
AAPL,08-03-2011, ,354.91,357.4,352.25,355.76,12718000 
AAPL,09-03-2011, ,354.69,354.76,350.6,352.47,16192700 
AAPL,10-03-2011, ,349.69,349.77,344.9,346.67,18138800 
AAPL,11-03-2011, ,345.4,352.32,345,351.99,16824200 

分析日期数据

from datetime import datetime
def datestr2num(s): 
 return datetime.strptime(s.decode("utf-8"), "%d-%m-%Y").date().weekday()



dates, close=np.loadtxt('data.csv', delimiter=',',  converters={1: datestr2num}, usecols=(1,6), unpack=True)

dates
array([4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 1.,
       2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4.])

averages = np.zeros(5)
for i in range(5):  
   indices = np.where(dates == i)   
   prices = np.take(close, indices)  
   avg = np.mean(prices)  
   print("Day", i, "prices", prices, "Average", avg  )
   averages[i] = avg


np.max(averages)  argmax函数返回的是averages数组中最大元素的索引值


NumPy的ndarray:一种多维数组对象

In [12]: import numpy as np

# Generate some random data
In [13]: data = np.random.randn(2, 3)

In [14]: data
Out[14]: 
array([[-0.2047,  0.4789, -0.5194],
       [-0.5557,  1.9658,  1.3934]])


In [15]: data * 10
Out[15]: 
array([[ -2.0471,   4.7894,  -5.1944],
       [ -5.5573,  19.6578,  13.9341]])

In [16]: data + data
Out[16]: 
array([[-0.4094,  0.9579, -1.0389],
       [-1.1115,  3.9316,  2.7868]])


#元素自身想运算

ndarray是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的。每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数组数据类型的对象)

创建ndarray

In [19]: data1 = [6, 7.5, 8, 0, 1]
In [20]: arr1 = np.array(data1)
In [21]: arr1
Out[21]: array([ 6. ,  7.5,  8. ,  0. ,  1. ])
  
  
  ##或
In [22]: data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
In [23]: arr2 = np.array(data2)  

除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组即可:

In [29]: np.zeros(10)
Out[29]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

In [30]: np.zeros((3, 6))
Out[30]: 
array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])

In [31]: np.empty((2, 3, 2))
Out[31]: 
array([[[ 0.,  0.],
        [ 0.,  0.],
        [ 0.,  0.]],
       [[ 0.,  0.],
        [ 0.,  0.],
        [ 0.,  0.]]])

arange是Python内置函数range的数组版:


ndarray的数据类型

In [33]: arr1 = np.array([1, 2, 3], dtype=np.float64)

In [34]: arr2 = np.array([1, 2, 3], dtype=np.int32)

In [35]: arr1.dtype
Out[35]: dtype('float64')

In [36]: arr2.dtype
Out[36]: dtype('int32')

数据类型转化

In [37]: arr = np.array([1, 2, 3, 4, 5])

In [38]: arr.dtype
Out[38]: dtype('int64')

In [39]: float_arr = arr.astype(np.float64)

In [40]: float_arr.dtype
Out[40]: dtype('float64')

如果将浮点数转换成整数,则小数部分将会被截取删除

如果某字符串数组表示的全是数字,也可以用astype将其转换为数值形式:

In [44]: numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)

In [45]: numeric_strings.astype(float)
Out[45]: array([  1.25,  -9.6 ,  42.  ])

注意:使用numpy.string_类型时,一定要小心,因为NumPy的字符串数据是大小固定的,发生截取时,不会发出警告。pandas提供了更多非数值数据的便利的处理方法。

NumPy数组的运算

不用编写循环即可对数据执行批量运算。NumPy用户称其为矢量化(vectorization)。大小相等的数组之间的任何算术运算都会将运算应用到元素级

In [51]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])

In [52]: arr
Out[52]: 
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

In [53]: arr * arr
Out[53]: 
array([[  1.,   4.,   9.],
       [ 16.,  25.,  36.]])

In [54]: arr - arr
Out[54]: 
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

数组与标量的算术运算会将标量值传播到各个元素: 计算动作会在每一个元素上执行

大小相同的数组之间的比较会生成布尔值数组:

不同大小的数组之间的运算叫做广播(broadcasting)

In [57]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])

In [58]: arr2
Out[58]: 
array([[  0.,   4.,   1.],
       [  7.,   2.,  12.]])

In [59]: arr2 > arr
Out[59]:
array([[False,  True, False],
       [ True, False,  True]], dtype=bool)

基本的索引和切片

当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传播(也就说后面将会讲到的“广播”)到整个选区。跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。

即: 对切片的操作会反应到源数据上,类似数据映射的关系

注意:如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如arr[5:8].copy()

在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray(它含有高一级维度上的所有数据)

In [76]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

arr3d[0]   #一个2×3数组

切片索引

二维数组arr2d:沿着第0轴(即第一个轴)切片的。也就是说,切片是沿着一个轴向选取元素的。表达式arr2d[:2]可以被认为是“选取arr2d的前两行”

In [90]: arr2d
Out[90]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [91]: arr2d[:2]
Out[91]: 
array([[1, 2, 3],
       [4, 5, 6]])

注意,“只有冒号”表示选取整个轴

In [95]: arr2d[:, :1]
Out[95]: 
array([[1],
       [4],
       [7]])

布尔型索引

In [98]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])

In [99]: data = np.random.randn(7, 4)

In [100]: names
Out[100]: 
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],
      dtype='<U4')

In [101]: data
Out[101]: 
array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
       [ 1.0072, -1.2962,  0.275 ,  0.2289],
       [ 1.3529,  0.8864, -2.0016, -0.3718],
       [ 1.669 , -0.4386, -0.5397,  0.477 ],
       [ 3.2489, -1.0212, -0.5771,  0.1241],
       [ 0.3026,  0.5238,  0.0009,  1.3438],
       [-0.7135, -0.8312, -2.3702, -1.8608]])


In [102]: names == 'Bob'
Out[102]: array([ True, False, False,  True, False, False, False], dtype=bool)
  
  
  
In [103]: data[names == 'Bob']
Out[103]: 
array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
       [ 1.669 , -0.4386, -0.5397,  0.477 ]])  

布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数(或整数序列,稍后将对此进行详细讲解)混合使用:

In [103]: data[names == 'Bob']
Out[103]: 
array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
       [ 1.669 , -0.4386, -0.5397,  0.477 ]])
       
       
In [104]: data[names == 'Bob', 2:]
Out[104]: 
array([[ 0.769 ,  1.2464],
       [-0.5397,  0.477 ]])

In [105]: data[names == 'Bob', 3]
Out[105]: array([ 1.2464,  0.477 ])       

要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:

data[~(names == 'Bob')]

##或
cond = names == 'Bob'
data[~cond]

选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可

mask = (names == 'Bob') | (names == 'Will')

通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的数组也是如此。

通过布尔型数组设置值是一种经常用到的手段。为了将data中的所有负值都设置为0,我们只需

data[data < 0] = 0

通过一维布尔数组设置整行或列的值也很简单:

data[names != 'Joe'] = 7

花式索引

花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引。假设我们有一个8×4数组:

原文地址:https://www.cnblogs.com/g2thend/p/12377656.html