了解扫描和应用中的边距的直观方法
An intuitive way to understand MARGIN in sweep and apply
我一直对 MARGIN 在 sweep
和 apply
中似乎意味着 2 个不同的东西感到困惑。考虑:
m <- matrix(1:6, ncol = 2)
# The "- 1" operation is applied to all cells in each row
sweep(m, MARGIN = 1, 1, "-")
# The sum operation is applied to each column
apply(m, MARGIN = 1, sum)
你有助记符来理解MARGIN这个看似矛盾的意思吗?
MARGIN 参数在两个函数中的含义完全相同,即逐行操作。我过去曾多次与 sweep
混淆,但我认为您与 apply
.
混淆
我正在打印下面的矩阵,以便稍后与 apply
和 sweep
进行直观比较:
> m
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
首先,当 MARGIN 为 1 时,sweep
函数执行逐行操作。我将稍微更改第三个参数,以便更明显:
> sweep(m, MARGIN = 1, 1:3, "-")
[,1] [,2]
[1,] 0 3
[2,] 0 3
[3,] 0 3
在上面的例子中,数字 1 从第 1 行减去,数字 2 从第 2 行减去,数字 3 从第 3 行减去。所以,很明显这是一个逐行操作。
现在让我们看看下面的apply
函数:
> apply(m, MARGIN = 1, sum)
[1] 5 7 9
很明显,矩阵有3行2列。很容易暗示这也是按行操作,因为我们有 3 个结果,即与行数相同。如果我们检查数字,也可以确认这一点。第 1 行求和为 5,第 2 行求和为 7,第 3 行求和为 9。
因此,很明显,两种情况下的 MARGIN 都意味着按行操作。
我觉得我需要加 2 美分。首先是我的助记词:
我的助记词:
我将 apply()
与 negative MARGINs 一起使用(即 apply(A, MARGIN=2, ...)
变为 --> apply(A, MARGIN=-1, ...)
,这使得行为与扫描一致(就绝对而言值)& 具有使 MARGIN 参数与 numpy/torch/matlab 轴参数一致的额外好处!例如,torch.mean(arr, axis=0)
== np.mean(arr, axis=0)
== apply(arr, MARGIN=-1, mean)
(当然 R 的保存base-1 索引)
这很容易记住,因为您实际上不能在 sweep
中使用负边距!因此,如果您忘记了哪个函数需要它们,它会立即提醒您错误。
关于不一致:
我相信你是对的 OP,R 核心团队确实在这里做出了不一致的功能(他们经常这样做)。简单的事实是,apply(A, MARGIN=1, ..., FUN=f)
意味着:将 FUN 复制并应用到 A 的每个 行 ,& sweep(A, MARGIN=1, ..., FUN=f)
意味着:将 FUN 复制并应用到每个 [=31= A.
的]列
尽管 LyzandeR 的助记符可能很有用,但我认为他对 row-wise 的定义过于模糊,并且在两个函数之间巧妙地改变了它的含义。
我一直对 MARGIN 在 sweep
和 apply
中似乎意味着 2 个不同的东西感到困惑。考虑:
m <- matrix(1:6, ncol = 2)
# The "- 1" operation is applied to all cells in each row
sweep(m, MARGIN = 1, 1, "-")
# The sum operation is applied to each column
apply(m, MARGIN = 1, sum)
你有助记符来理解MARGIN这个看似矛盾的意思吗?
MARGIN 参数在两个函数中的含义完全相同,即逐行操作。我过去曾多次与 sweep
混淆,但我认为您与 apply
.
我正在打印下面的矩阵,以便稍后与 apply
和 sweep
进行直观比较:
> m
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
首先,当 MARGIN 为 1 时,sweep
函数执行逐行操作。我将稍微更改第三个参数,以便更明显:
> sweep(m, MARGIN = 1, 1:3, "-")
[,1] [,2]
[1,] 0 3
[2,] 0 3
[3,] 0 3
在上面的例子中,数字 1 从第 1 行减去,数字 2 从第 2 行减去,数字 3 从第 3 行减去。所以,很明显这是一个逐行操作。
现在让我们看看下面的apply
函数:
> apply(m, MARGIN = 1, sum)
[1] 5 7 9
很明显,矩阵有3行2列。很容易暗示这也是按行操作,因为我们有 3 个结果,即与行数相同。如果我们检查数字,也可以确认这一点。第 1 行求和为 5,第 2 行求和为 7,第 3 行求和为 9。
因此,很明显,两种情况下的 MARGIN 都意味着按行操作。
我觉得我需要加 2 美分。首先是我的助记词:
我的助记词:
我将 apply()
与 negative MARGINs 一起使用(即 apply(A, MARGIN=2, ...)
变为 --> apply(A, MARGIN=-1, ...)
,这使得行为与扫描一致(就绝对而言值)& 具有使 MARGIN 参数与 numpy/torch/matlab 轴参数一致的额外好处!例如,torch.mean(arr, axis=0)
== np.mean(arr, axis=0)
== apply(arr, MARGIN=-1, mean)
(当然 R 的保存base-1 索引)
这很容易记住,因为您实际上不能在 sweep
中使用负边距!因此,如果您忘记了哪个函数需要它们,它会立即提醒您错误。
关于不一致:
我相信你是对的 OP,R 核心团队确实在这里做出了不一致的功能(他们经常这样做)。简单的事实是,apply(A, MARGIN=1, ..., FUN=f)
意味着:将 FUN 复制并应用到 A 的每个 行 ,& sweep(A, MARGIN=1, ..., FUN=f)
意味着:将 FUN 复制并应用到每个 [=31= A.
尽管 LyzandeR 的助记符可能很有用,但我认为他对 row-wise 的定义过于模糊,并且在两个函数之间巧妙地改变了它的含义。