《Python数据分析》和《利用Python进行数据分析》
本期将会涉及到Python模块中的numpy,这是一个处理数组的强大模块,而该模块也是其他数据分析模块(如pandas和scipy)的核心。下面将从这5个方面来介绍numpu模块的内容:
1)数组的创建
2)有关数组的属性和函数
3)数组元素的获取--普通索引、切片、布尔索引和花式索引
4)统计函数与线性代数运算
5)随机数的生成
数组的创建
array的首个参数一定是一个序列,可以是元组也可以是列表。
一维数组的创建
可以使用numpy中的arange()函数创建一维有序数组,它是内置函数range的扩展版。
In [1]:
In [2]:
In [3]:
Out[3]:
In [4]:
Out[4]:
In [5]:
In [6]:
Out[6]:
In [7]:
Out[7]:
通过arange生成的序列就不是简简单单的列表类型了,而是一个一维数组。
如果一维数组不是一个规律的有序元素,而是人为的输入,就需要array()函数创建了。
In [8]:
In [9]:
Out[9]:
In [10]:
Out[10]:
上面是由元组序列构成的一维数组。
In [11]:
In [12]:
Out[12]:
In [13]:
Out[13]:
上面是由列表序列构成的一维数组。
二维数组的创建
列表套列表或元组套元组。
In [14]:
In [15]:
Out[15]:
array([[ 1, 1, 2, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
上面使用元组套元组的方式。
In [16]:
In [17]:
Out[17]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
上面使用列表套列表的方式。
高维数组在将来的数据分析中用的比较少,这里关于高维数组的创建就不赘述了,构建方法仍然是套的方式。
上面所介绍的都是人为设定的一维、二维或高维数组,numpy中也提供了几种特殊的数组,它们是:
In [18]:
Out[18]:
In [19]:
Out[19]:
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
In [20]:
Out[20]:
In [21]:
Out[21]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
In [22]:
Out[22]:
In [23]:
Out[23]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
有关数组的属性和函数
当一个数组构建好后,我们看看关于数组本身的操作又有哪些属性和函数:
In [24]: arr3
Out[24]:
array([[ 1, 1, 2, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
In [25]:
Out[25]:
In [26]:
Out[26]:
In [27]:
In [28]:
Out[28]:
In [29]:
In [30]:
Out[30]:
ravel方法生成的是原数组的视图,无需占有内存空间,但视图的改变会影响到原数组的变化。而flatten方法返回的是真实值,其值的改变并不会影响原数组的更改。
通过下面的例子也许就能明白了:
In [31]: b[:3] = 0
In [32]:
Out[32]:
array([[ 1, 1, 2, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
通过更改b的值,原数组没有变化。
In [33]:
In [34]:
Out[34]:
array([[ 0, 0, 0, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
a的值变化后,会导致原数组跟着变化。
In [35]:
Out[35]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
In [36]:
Out[36]:
In [37]:
Out[37]:
In [38]:
Out[38]:
array([[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11],
[ 4, 8, 12]])
如果数组的数据类型为复数的话,real方法可以返回复数的实部,imag方法返回复数的虚部。
哪些函数可操作:
In [39]:
Out[39]:
In [40]:
Out[40]:
array([[ 0, 0, 0, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
In [41]:
Out[41]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
In [42]:
Out[42]:
array([[ 0, 0, 0, 3, 1, 2, 3, 4],
[ 5, 8, 13, 21, 5, 6, 7, 8],
[ 34, 55, 89, 144, 9, 10, 11, 12]])
横向拼接arr3和arr4两个数组,但必须满足两个数组的行数相同。
In [43]:
Out[43]:
array([[ 0, 0, 0, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144],
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
纵向拼接arr3和arr4两个数组,但必须满足两个数组的列数相同。
In [44]:
Out[44]:
array([[ 0, 0, 0, 3, 1, 2, 3, 4],
[ 5, 8, 13, 21, 5, 6, 7, 8],
[ 34, 55, 89, 144, 9, 10, 11, 12]])
In [45]:
Out[45]:
array([[ 0, 0, 0, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144],
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
reshape()函数和resize()函数可以重新设置数组的行数和列数:
In [46]:
In [47]:
Out[47]:
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])
In [48]:
In [49]:
Out[49]:
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]])
通过reshape函数将一维数组设置为二维数组,且为4行6列的数组。
In [50]:
In [51]:
Out[51]:
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]])
通过resize函数会直接改变原数组的形状。
数组转换:tolist将数组转换为列表,astype()强制转换数组的数据类型,下面是两个函数的例子:
In [53]:
In [54]:
Out[54]:
[[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]
In [55]:
Out[55]:
In [56]:
In [57]:
Out[57]:
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.]])
In [58]:
Out[58]:
In [59]:
Out[59]:
数组元素的获取
通过索引和切片的方式获取数组元素,一维数组元素的获取与列表、元组的获取方式一样:
In [60]:
In [61]: arr7
Out[61]:
In [62]:
Out[62]:
In [63]:
Out[63]:
In [64]:
Out[64]:
In [65]:
Out[65]:
In [66]:
Out[66]:
二维数组元素的获取:
In [67]: arr8 = np.array(np.arange(12)).reshape(3,4)
In [68]:
Out[68]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [69]:
Out[69]:
In [70]:
Out[70]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
In [71]:
Out[71]:
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11]])
In [72]:
Out[72]:
In [73]:
Out[73]:
array([[ 2, 3],
[ 6, 7],
[10, 11]])
In [74]:
Out[74]:
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
In [75]:
Out[75]:
布尔索引,即索引值为True和False,需要注意的是布尔索引必须输数组对象。
In [76]: log = np.array([True,False,False,True,True,False])
In [77]:
In [78]:
Out[78]:
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]])
In [79]:
Out[79]:
array([[ 0, 1, 2, 3],
[12, 13, 14, 15],
[16, 17, 18, 19]])
In [80]:
Out[80]:
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[20, 21, 22, 23]])
举一个场景,一维数组表示区域,二维数组表示观测值,如何选取目标区域的观测?
In [81]: area = np.array(['A','B','A','C','A','B','D'])
In [82]:
Out[82]:
array(['A', 'B', 'A', 'C', 'A', 'B', 'D'],
dtype='<U1')
In [83]:
In [84]:
Out[84]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17],
[18, 19, 20]])
In [85]:
Out[85]:
array([[ 0, 1, 2],
[ 6, 7, 8],
[12, 13, 14]])
返回所有A区域的观测。
In [86]:
Out[86]:
array([[ 0, 1, 2],
[ 6, 7, 8],
[12, 13, 14],
[18, 19, 20]])
返回所有A区域和D区域的观测。
当然,布尔索引也可以与普通索引或切片混合使用:
In [87]:
Out[87]:
array([[ 0, 2],
[ 6, 8],
[12, 14]])
返回A区域的所有行,且只获取第1列与第3列数据。
花式索引:实际上就是将数组作为索引将原数组的元素提取出来
In [88]: arr10 = np.arange(1,29).reshape(7,4)
In [89]:
Out[89]:
array([[ 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, 27, 28]])
In [90]:
Out[90]:
array([[17, 18, 19, 20],
[ 5, 6, 7, 8],
[13, 14, 15, 16],
[21, 22, 23, 24]])
In [91]:
Out[91]:
array([[17, 19, 20],
[ 5, 7, 8],
[21, 23, 24]])
In [92]:
Out[92]:
请注意!这与上面的返回结果是截然不同的,上面返回的是二维数组,而这条命令返回的是一维数组