Numpy:数组合矢量计算

Numpy, 数组和矢量计算包

前几年前想学数据分析,于是就去学习Python的Numpy。然而看完《利用Python进行数据分析》后,也对它没有多大印象的。但是学了一段时间R语言,并且将R语言和Python进行一些比较,再次学习Numpy就特别轻松了。

由于学过R语言,我可以简单认为Numpy提供的多维数据对象ndarray就是Python版本的R语言的vector, matrixarray。几乎没有特殊说明,这两者的任何操作都是一致的。

Numpy的部分功能如下:

  • ndarray, 一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组
  • 用于对整组数据进行快速运算的标准数学函数(无需编写循环函数)
  • 用于读写磁盘数据的工具以及用于操作内存映射文件的工具
  • 线性代数, 随机数生成以及傅里叶变换功能
  • 用于继承由C, C++, Fortran等语言编写的代码的工具

约定俗成:

import numpy as np

也就说不会特意去声明导入numpy

创建多维数组

多维数组有多种创建方法,其中最简单的就是使用arrary函数。以一切序列类型的对象作为输入

# 一维数组,也就是R语言的最基本元素,vector
In [1]: import numpy as np
In [2]: data1 = [1,2,3,4,5]
In [3]: arr1 = np.array(data1)
In [4]: ?arr1 # 内省下arr1对象
# 二维数组,也就是R语言的matrix
In [5]: data2 = [[1,2,3],[4,5,6]]
In [6]: arr2 = np.array(data2)
In [7]: ?arr2
# 在R语言中用dim(), nrows, ncols查看数据维度
# 在Python中,这些可以用对象的方法查看。
In [10]: arr2.ndim
Out[10]: 2
In [11]: arr2.shape
Out[11]: (2, 3)
# 和R语言一样,ndarray的对象不允许存在多种数据类型
# ndarray会自动根据输入选择最合适的数据类型
In [17]: data3 = [1,"string", True]
In [18]: arr3 = np.array(data3)
In [19]: arr3
Out[19]: 
array(['1', 'string', 'True'], 
      dtype='<U11')
In [20]: arr3.dtype
Out[20]: dtype('<U11')

除了用array转换序列型数据输入以外,还可以用arange(类似于内置的ranges), asarray(类似于array)。后面的方法和线性代数密切相关,建议查看相应的说明: ones ones_like, zeros zeros_like empty empty_like,eye identity

关于数据类型, 一般情况下我们没必要对它太过于关注。但是对于大数据集,则需要自己主动声明。因为数据类型(dtype)负责将一块内存解释为特定数据类型,即直接映射到相应的机器表示。在R语言中有一类类型转换函数(例如as.numeric)对数组内的数据类型进行转换,在Numpy则通过dtype.

数组运算

R语言的一大特点就是矢量化运算,能用来检查你是否理解R语言。简单理解,就是不用循环就能对数据批量运算。

个人愚见:矢量化运算是Numpy用C语言编写,在C语言层面是也是循环。这也是为什么一个数组内的数据类型要一致。

# R
> arr1
[1] 1 2 3 4 5
> arr1 + 1
[1] 2 3 4 5 6
# Python
In [29]: arr1 + 1
Out[29]: array([2, 3, 4, 5, 6])
In [35]: arr2 * 3
Out[35]: array([[ 3,  6,  9],
       [12, 15, 18]])
In [36]: arr2 * arr2
Out[36]: array([[ 1,  4,  9],
       [16, 25, 36]])      

我曾经在 Python和R的异同(一)里谈到原生Python要想实现R语言的矢量化就要使用列表推导式, 而目前可以用numpy带来的矢量化运算属性了。

索引和切片

切片

在R语言和Numpy,包括原生的Python都有切片的功能, 所谓的切片(slicing) 就是从已有的数组中返回选定的元素,而索引(index)提供指向存储在数组指定位置的数据值的指针

# R
arr <-  0:9
arr_sub <- arr[1:5]
# Python default list
data = [i for i in range(10)]
data_sub = data[0:5]
# Python Numpy
arr = np.arange(10)
arr_sub = arr[0:5]

上面的结果都是一致的,都是提取前5个元素。只不过要注意R语言的索引从1开始(5-1+1),而Python从0开始(5-0)。表面看起来是相同的,但其实Numpy切片得到只是原始数据的视图(view),也就是浅复制,即你对Numpy切片后的数据进行操作,会影响到原始数据。

# Python Numpy
In [60]: arr_sub[1] = 100
In [61]: arr
Out[61]: array([  0, 100,   2,   3,   4,   5,   6,   7,   8,   9])
# Python default list
In [65]: data_sub[1] = 100
In [66]: data_sub
Out[66]: [0, 100, 2, 3, 4]
In [67]: data
Out[67]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# R 同Python默认的列表

原因就是Numpy的目的是处理大数据,对大规模的数据进行实际复制会消耗不必要的性能和内存。

numpy的索引操作和R语言几乎一模一样,分为切片索引,布尔值索引,花式索引。这些都在《R语言实战》基本数据管理章节中的数据集选取子集里面提及。

切片索引:

In [79]: arr = np.eye(9,9)
## 类似于R的操作
In [80]: arr[1,1]
Out[80]: 1.0
In [82]: arr[:,:]
## Python原来是通过递归对元素进行访问
In [81]: arr[1][1]
Out[81]: 1.0

布尔值索引, 也就是先产生一个True, False的数组,然后根据这个数组提取数据

In [87]: arr[arr == 1]
Out[87]: array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])

花式索引, 就是提供指定顺序的整数型列表

In [94]:  arr = np.empty((8,4))
In [95]: for i in range(8):
    ...:     arr[i] = i
    ...:
## 选取第4,3,1,6行数据
In [99]: arr[[3,2,0,5]]
Out[99]: array([ 3.,  2.,  0.,  5.])
## 在R里面就是
## arr[c(4,3,1,6)]

注意,如果一次性传入多个索引数据,Numpy会返回一维数组,但是R依旧会返回多维。这是目前第一个与R不太一样,当然和预想的结果也不同。

# R
> mdata <- matrix(1:32,nrow=8, ncol=4)
> mdata[c(2,6,8,2),c(1,4,2,3)]
     [,1] [,2] [,3] [,4]
[1,]    2   26   10   18
[2,]    6   30   14   22
[3,]    8   32   16   24
[4,]    2   26   10   18
# Numpy
In [110]: arr = np.arange(1,33).reshape(8,4)
In [111]: arr[[1,5,7,2],[0,3,1,2]]
Out[111]: array([ 5, 24, 30, 11])
## 为了解决这个问题,有两种方法
In [112]: arr[[1,5,7,2]][:,[0,3,1,2]]
Out[112]: 
array([[ 5,  8,  6,  7],
       [21, 24, 22, 23],
       [29, 32, 30, 31],
       [ 9, 12, 10, 11]])
In [113]: arr[np.ix_([1,5,7,2],[0,3,1,2])]
Out[113]: 
array([[ 5,  8,  6,  7],
       [21, 24, 22, 23],
       [29, 32, 30, 31],
       [ 9, 12, 10, 11]])

: 花式索引以及布尔值索引和切片索引不同, 前者将数据复制到新的数组中,而后者是原始数据的视图。 可能原因是前两者的得到数据在原始数据中位置不是整块存放。

数据转置和轴对换

转置(transpose)是数据重塑的一种特殊形式,返回的是原始数据的视图(这一点和R不同)。数组不仅有transpose方法,还有一个T属性, 这两者在二维数组上是相同的。

arr = np.arange(1,33).reshape(8,4)
arr.T
np.transpose(arr)
# 线性代数的矩阵内积
np.dot(arr.T, arr)

但是在更高维度上,T属性依旧还是轴对换,transpose方法还需要提供轴编号组成的元组,这个真的是非常难以理解。

通用函数:快速的元素级数组函数

我曾经写过一篇文章,叫做R语言的数据管理里面提到了基石函数,来源于《R语言实战》的高级数学管理。在numpy,这类函数叫做通用函数(UNIVERSAL FUNCTIONS, UFUNC),能够进行矢量化运算的函数。按照官方文档的划分,大致分为

  • 数学运算
  • 三角函数
  • 位运算函数
  • 比较函数
  • 浮点函数

按照《利用Pyton进行数据分析》可以分为一元函数和二元函数。

对于一些自定义的函数,R语言采用的apply家族函数进行矢量化操作,避免循环。而在Numpy则是frompyfunc。不过这已经比较高级了。

Numpy更多是Python进行科学计算的基础包,因此数据分析部分的内容就交给pandas吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容