码迷,mamicode.com
首页 > 编程语言 > 详细

Python数据分析(二): Numpy技巧 (1/4)

时间:2017-10-05 22:39:46      阅读:526      评论:0      收藏:0      [点我收藏+]

标签:upload   qualifier   audio   rdp   rate   minus   title   pinterest   ppi   

 

In [1]:
import numpy
numpy.__version__
Out[1]:
‘1.13.1‘
In [2]:
import numpy as np
 

?? Python的数据类型?

与C语言不同, Python是动态语言。
在C语言中,变量的数据类型是事先声明好的,在Python中变量的类型是动态推测出来的。
Python的变量不仅仅是值,还包含其他的信息。

 

例如:Python中的整型数值不仅仅是个整型。Python是用C实现的,Python的对象就是C的结构的伪装,不仅仅包含值,还包含其他信息。
x = 10000,这里x不仅仅是个整数,它的结构大约是这样的:
struct _longobject { long ob_refcnt; PyTypeObject *ob_type; size_t ob_size; long ob_digit[1]; };

 

Python中的整型包括4部分:

  • ob_refcnt: 一个引用计数,帮助python处理内存分配和释放。
  • ob_type: 对变量的类型进行编码。
  • ob_size: 指定数据成员的大小。
  • ob_digit: 真实的整型值在这。
 

C和Python中int的对比图

技术分享技术分享 其中PyObject_HEAD就包含在reference count、type code和前边提到的其他的信息。

 

??Python的List不仅仅是List?

Python的List可以是异构的:

In [3]:
L = [True, 3, "Hello"]
 

Python的List的这种特点也是有代价的,List里面的每一项都有自己的类型信息、reference count和其他信息。所以每一项都是一个完整的python对象。
但是在特殊的情况下,例如,List里面所有的项的类型都是一样的话,那这些信息就太多余了,所以一个固定类型的数组(例如Numpy的数组)会更有效率。
在实现上:这种数组应该是由一个指针指向连续的数据块;而Python的List则是一个指针指向一堆指针,这些指针每个都指向一个完整的python对象。
Numpy的数组确实缺少了这种灵活,但是对于数据的存储和操作却更有效率。

技术分享
技术分享

 

Python 内置的 Array?

python有一个内置的array模块,可以用来创建同一类型的数组。

In [4]:
import array
L = list(range(10))
A = array.array(‘i‘, L) ### i是类型代码,表示是整型
A
Out[4]:
array(‘i‘, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
 

??Numpy的ndarray?

python的array为数组类型的数据提供了有效率的存储。而Numpy的ndarray还能对数据进行更有效率的操作

 

??从List创建Numpy数组?

可以使用np.array这个函数。

In [5]:
np.array([1, 2, 3, 4, 5])
Out[5]:
array([1, 2, 3, 4, 5])
 

和python的List不一样,numpy数组的数据类型必须是一样的。如果类型不一样,那么numpy会尽力去向上转型(如果可能的话)。例如:

In [6]:
np.array([3.14, 4, 14])
Out[6]:
array([  3.14,   4.  ,  14.  ])
 

明确的设定数组的数据类型?

可以使用dtype这个关键字:

In [7]:
np.array([1, 2, 3], dtype=‘float32‘)
Out[7]:
array([ 1.,  2.,  3.], dtype=float32)
 

numpy数组可以多维?

这点和python的list不一样。

In [8]:
np.array([range(i, i + 3) for i in [2, 4, 6]])
Out[8]:
array([[2, 3, 4],
       [4, 5, 6],
       [6, 7, 8]])
 

??从头创建numpy数组?

In [9]:
np.zeros(10, dtype=int) # 长度为10的,都是0的数组。
Out[9]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [10]:
np.ones((3, 5), dtype=float) # 3 x 5维的成员都是1,类型是float的二维数组。
Out[10]:
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
In [11]:
np.full((3, 5), 3.14) # 3x5数组,成员都是3.14
Out[11]:
array([[ 3.14,  3.14,  3.14,  3.14,  3.14],
       [ 3.14,  3.14,  3.14,  3.14,  3.14],
       [ 3.14,  3.14,  3.14,  3.14,  3.14]])
In [12]:
np.arange(0, 20, 2.2) # 与python的range类似,但允许小数步长。
Out[12]:
array([  0. ,   2.2,   4.4,   6.6,   8.8,  11. ,  13.2,  15.4,  17.6,  19.8])
In [13]:
np.linspace(0, 1, 5) # 数组的成员是从0到1把区间平均分成5-1份的值
Out[13]:
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])
In [14]:
np.random.random((3, 3)) # 3x3均匀分布的,值是0到1的随机数组
Out[14]:
array([[ 0.23189907,  0.16073633,  0.9284715 ],
       [ 0.76578217,  0.9150627 ,  0.34172519],
       [ 0.4319254 ,  0.1280663 ,  0.72952746]])
In [15]:
np.random.normal(0, 1, (3, 3)) # 3x3正态分布的随机值数组,平均值为0,标准差为1
Out[15]:
array([[ 0.28705737, -0.33676174, -0.56374917],
       [ 0.16447215,  0.40251098,  1.11612127],
       [-1.6724113 ,  0.9027976 ,  0.75619702]])
In [16]:
np.eye(3) # 3x3单位矩阵
Out[16]:
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
In [17]:
np.empty(3) # 创建一个有三个整型但未初始化的数组,其元素的值就是那个位置的内存上恰好存在的数据。
Out[17]:
array([ 1.,  1.,  1.])
 

??Numpy标准数据类型?

当创建数组的时候,可以通过字符串或者numpy的对象来指定类型:

In [18]:
np.zeros(10, dtype=‘int16‘);
np.zeros(10, dtype=np.int16);
 

numpy的数据类型:

技术分享 技术分享

 

??Numpy 数组基本知识?

 

?? 属性?

 

每个numpy数据都有这几个属性:

  • ndim:维数
  • shape:每个维的大小
  • size:数组的总大小
  • dtype:数组成员的类型
  • itemsize:数组每个成员的大小 byte
  • nbytes: 数组的总大小 byte
In [19]:
np.random.seed(0) # seed for reproducibility
x1 = np.random.randint(10, size=6)
x2 = np.random.randint(10, size=(3, 4))
x3 = np.random.randint(10, size=(3, 4, 5))
print("x3 ndim: ", x3.ndim)
print("x3 shape:", x3.shape)
print("x3 size: ", x3.size)
print("x3 dtype: ", x3.dtype)
print("itemsize: ", x3.itemsize, "bytes")
print("nbytes: ", x3.nbytes, "bytes")
 
x3 ndim:  3
x3 shape: (3, 4, 5)
x3 size:  60
x3 dtype:  int32
itemsize:  4 bytes
nbytes:  240 bytes
 

?? 数组索引?

In [20]:
x = [1, 2, 3, 4, 5]
x[2]
Out[20]:
3
In [21]:
x[-1] # 最后一个元素
Out[21]:
5
 

多维数组的索引?

In [22]:
x2 = np.array([[1,2,3,4], [5,6,7,8], [3,4,5,6]])
print(x2)
print(x2[0, 0])
print(x2[2, -1])
 
[[1 2 3 4]
 [5 6 7 8]
 [3 4 5 6]]
1
6
 

记住,numpy数组的数据类型是一定的,如果你向一个整数数组插入一个浮点类型的数据,那么这个数据会被截断的。

In [23]:
x2[0] = 3.14159 
x2
Out[23]:
array([[3, 3, 3, 3],
       [5, 6, 7, 8],
       [3, 4, 5, 6]])
 

?? 切割数组?

 

numpy数组切割需要使用切割符号,也就是冒号 :。形式如下:
x[开始:结束:步长]
如果这里有任何一个参数没有填写,那么他们的默认值分别是:
开始=0,结束=数组的长度,步长=1

 

一维数组?

In [24]:
x = np.arange(10)
print(x)
print(x[:4])
print(x[4:])
print(x[4:7])
print(x[::2])
print(x[1::2])
print(x[::-1]) # 所有元素倒序
print(x[5::-2]) # 从索引5各数倒序
 
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3]
[4 5 6 7 8 9]
[4 5 6]
[0 2 4 6 8]
[1 3 5 7 9]
[9 8 7 6 5 4 3 2 1 0]
[5 3 1]
 

多维数组?

In [25]:
x2
Out[25]:
array([[3, 3, 3, 3],
       [5, 6, 7, 8],
       [3, 4, 5, 6]])
In [26]:
x2[:2, :3] # 前两行,前三列
Out[26]:
array([[3, 3, 3],
       [5, 6, 7]])
In [27]:
x2[:, ::2] # 所有的行,隔列选取
Out[27]:
array([[3, 3],
       [5, 7],
       [3, 5]])
In [28]:
x2[::-1, ::-1] # 行列都倒序
Out[28]:
array([[6, 5, 4, 3],
       [8, 7, 6, 5],
       [3, 3, 3, 3]])
In [29]:
# 访问行或列
x2[:, 2] # 第一列
Out[29]:
array([3, 7, 5])
In [30]:
x2[0, :] # 第一行
Out[30]:
array([3, 3, 3, 3])
 

numpy数组的切割默认返回的是视图而不是数据的拷贝,这一点跟python的list不同,pythonlist默认进行数据的拷贝。

In [31]:
x2
Out[31]:
array([[3, 3, 3, 3],
       [5, 6, 7, 8],
       [3, 4, 5, 6]])
In [32]:
x2_sub = x2[:2, :2]
x2_sub
Out[32]:
array([[3, 3],
       [5, 6]])
In [33]:
x2_sub[0, 0] = 100
print(x2)
 
[[100   3   3   3]
 [  5   6   7   8]
 [  3   4   5   6]]
 

创建数组的拷贝?

需要对数组/子数组进行拷贝的话,就需要调用copy()方法。

In [34]:
x2
Out[34]:
array([[100,   3,   3,   3],
       [  5,   6,   7,   8],
       [  3,   4,   5,   6]])
In [35]:
x2_sub_cp = x2[:2, :2].copy()
x2_sub_cp
Out[35]:
array([[100,   3],
       [  5,   6]])
In [36]:
x2_sub_cp[0, 0] = 99
print(x2_sub_cp)
print(x2)
 
[[99  3]
 [ 5  6]]
[[100   3   3   3]
 [  5   6   7   8]
 [  3   4   5   6]]
 

?? Reshaping 重塑形?

 

把1到9这9个数,塑形为3x3数组:?

In [43]:
grid = np.arange(1, 10).reshape((3, 3))
grid
Out[43]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
 

这里的要求是第一个数组的size和reshape后的size要一致。
在可能的情况下,reshape方法会尽量使用第一个数组的视图而不是复制它,但是对于非连续的内存缓冲区,这就不一定了。

把一维数组塑形为二维数组(增加一个维)?

In [46]:
x = np.array([1,2,3])
x.reshape(1, 3) # 把一维数组变成 1x3二维数组
Out[46]:
array([[1, 2, 3]])
 

这里也可以在切割操作中使用np.newaxis这个关键字,来达到同样的效果

In [47]:
x[np.newaxis, :]
Out[47]:
array([[1, 2, 3]])
 

np.newaxis可以这样理解:x的原来的shape是(3,),使用切割操作创建数组,如果newaxis出现在第一个位置,那么新数组的shape就是x的shape左边加上1维:(3,) => (1, 3);如果newaxis出现在第二个位置,那么就是 (3,) => (3, 1)

In [49]:
x[:, np.newaxis]
Out[49]:
array([[1],
       [2],
       [3]])
 

?? 数组的连接和分割?

连接数组?

  • np.concatenate
  • np.vstack
  • np.hstack
 

np.concatenate的第一个参数是tuple或者数组的list:?

In [53]:
 x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
print(np.concatenate([x, y]))
z = [99, 99, 99]
print(np.concatenate([x, y, z]))
 
[1 2 3 3 2 1]
[ 1  2  3  3  2  1 99 99 99]
 

二维数组?

In [58]:
grid = np.array([[1, 2, 3], [4, 5, 6]])
np.concatenate([grid, grid]) # 沿着第一轴
Out[58]:
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
In [59]:
np.concatenate([grid, grid], axis=1) # 沿着第二轴
Out[59]:
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
 

不同维数的数组连接?

可以使用np.vstack(垂直)或np.hstack(水平)

In [60]:
x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7], [6, 5, 4]])
y = np.array([[99],[99]])
print(np.vstack([x, grid]))
print(np.hstack([y, grid]))
 
[[1 2 3]
 [9 8 7]
 [6 5 4]]
[[99  9  8  7]
 [99  6  5  4]]
 

np.dstack 沿着第三轴进行连接

 

分割数组?

  • np.split
  • np.vsplit
  • np.hsplit

第二个参数是索引的list,这些索引作为分割点。

In [61]:
x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
 
[1 2 3] [99 99] [3 2 1]
 

N个分割点会出现N+1个子数组。
np.vsplit和np.hsplit也类似:

In [63]:
grid = np.arange(16).reshape((4, 4))
grid
upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
left, right = np.hsplit(grid, [2])
print(left)
print(right)
 
[[0 1 2 3]
 [4 5 6 7]]
[[ 8  9 10 11]
 [12 13 14 15]]
[[ 0  1]
 [ 4  5]
 [ 8  9]
 [12 13]]
[[ 2  3]
 [ 6  7]
 [10 11]
 [14 15]]
 

np.dsplit 会沿着第三轴进行分割。

原始图片:技术分享

Python数据分析(二): Numpy技巧 (1/4)

标签:upload   qualifier   audio   rdp   rate   minus   title   pinterest   ppi   

原文地址:http://www.cnblogs.com/cgzl/p/7630065.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!