Author: hyacz<hyacz@foxmail.com>
Date: 2018-08-06
Version: 0.1
本文旨在帮助有一定编程基础的 R 语言用户迁移到 Python3,亦可作为两种语言的速查表使用。本文档受到这篇文章[1]的启发,在其基础上更新了一些过时的内容,并补充了许多新版本的内容与个人实践的结果。R 和 Python 都是很棒的工具,本文不想去讨论语言优劣。本文主要会从科学计算的角度展示 Python 与 R 的等价操作。
[1] http://mathesaurus.sourceforge.net/r-numpy.html
Time-stamp: "2007-11-09T16:46:36 vidar"
©2006 Vidar Bronken Gundersen, /mathesaurus.sf.net
Permission is granted to copy, distribute and/or modify this document as long as the above attribution is retained.
描述 | R | Python |
---|---|---|
赋值 | a <- 1 |
a = 1 |
加法 | a + b |
a + b |
减法 | a - b |
a - b |
乘法 | a * b |
a * b |
除法 | a / b |
a / b |
幂运算 | a ^ b |
a ** b |
取余 | a %% b |
a % b |
整数除法 | a %/% b |
a // b |
阶乘 | factorial(a) |
np.factorial(a) |
注: python 中 numpy.math.factorial 和 scipy.math.factorial 实际上都是 math.factorial 为了保持引用简洁,在引用 numpy 之后不再显式的调用 math.factorial。
>>> import scipy, numpy, math
>>> scipy.math.factorial.__self__, numpy.math.factorial.__self__, math.factorial.__self__
(<module 'math' from '/usr/.../math.cpython-37m-darwin.so'>,
<module 'math' from '/usr/.../math.cpython-37m-darwin.so'>,
<module 'math' from '/usr/.../math.cpython-37m-darwin.so'>)
描述 | R | Python |
---|---|---|
等于 | a == b |
a == b |
不等 | a != b |
a != b |
大于 | a > b |
a > b |
小于 | a < b |
a < b |
大于等于 | a >= b |
a >= b |
小于等于 | a <= b |
a <= b |
逻辑操作 | a,b类型 | 返回值类型 | R | Python |
---|---|---|---|---|
与 | 布尔变量 | 布尔变量 | a && b |
a and b |
或 | 布尔变量 | 布尔变量 | `a | |
非 | 布尔变量 | 布尔变量 | !a |
not a |
与(短路) | 布尔变量/向量 | 布尔变量 | a && b |
np.all(np.logical_and(a, b)) |
或(短路) | 布尔变量/向量 | 布尔变量 | `a | |
与(逐个) | 布尔变量/向量 | 布尔变量/向量 | a & b |
np.logical_and(a, b) |
或(逐个) | 布尔变量/向量 | 布尔变量/向量 | `a | b` |
异或(逐个) | 布尔变量/向量 | 布尔变量/向量 | xor(a, b) |
np.logical_xor(a,b) |
非(逐个) | 布尔变量/向量 | 布尔变量/向量 | !a |
~a or np.logical_not(a) |
注:Python 中没有与 R 中短路操作( &&、||
)直接等价的操作,需通过组合函数。从上表可知,Python 在处理逻辑变量列表时不要使用原生的逻辑关键字,需使用numpy中的函数。
描述 | R | Python |
---|---|---|
Not a Number | NaN | np.nan |
Not Available | NA | None |
注:NaN 和 NA 各有各的用法,需要注意如果将 None 混入数字型向量中,这会使得 sum 之类的函数直接报错崩溃;而当向量中存在 np.nan 的时候 sum 之类的操作会得到同为 nan 的结果(和 R 行为相同)。
利用 det() != 0
来判断矩阵是否可逆是不严谨的,有一些矩阵可能 det()
的值不等于 0,但是非常非常小,在理论上该矩阵是可以求逆的,但是由于计算机的精度是有限的,导致该矩阵是 “computationally singular” 的。要计算矩阵的二范数,当矩阵的二范数小于 1 / 计算精度
的时候矩阵才是可利用计算机求逆的。
# R
if (kappa(A) < 1 / .Machine$double.eps) {
Ai <- solve(A)
}
# Python
import numpy as np
from numpy import linalg as LA
if LA.cond(A) < 1 / np.finfo(A).eps:
Ai = LA.inv(A)
但是直接去计算二范数是比较慢的,考虑到速度问题更为常见的作法是利用 try ... catch
的方法来捕获求逆的错误,转而求伪逆。对于可逆的矩阵,直接求逆会比求伪逆在速度上有一定的优势。
# R
library(MASS)
Ai <- try(solve(A), silent=TRUE)
if (inherits(Ai, "try-error")) {
Ai <- ginv(Ai)
}
# python
from numpy import linalg as LA
try:
Ai = LA.inv(A)
except LA.LinAlgError:
Ai = LA.pinv(A)
在 python 中推荐使用 https://github.com/tqdm/tqdm 来产生进度条。