【问题标题】:Python numpy or pandas equivalent of the R function sweep()Python numpy 或 pandas 等效于 R 函数 sweep()
【发布时间】:2014-05-31 19:36:03
【问题描述】:

什么是 numpypandas 等效于 R 函数 sweep()

详细说明:在 R 中,假设我们有一个系数向量,比如 beta(数字类型)和一个数组,比如 data(20x5 数字类型)。我想将向量叠加在数组的每一行上并乘以相应的元素。然后返回结果 (20x5) 数组,我可以使用 sweep() 来实现这一点。

等效样例R代码:

beta <-  c(10, 20, 30, 40)
data <- array(1:20,c(5,4))
sweep(data,MARGIN=2,beta,`*`)
#---------------
 > data
      [,1] [,2] [,3] [,4]
 [1,]    1    6   11   16
 [2,]    2    7   12   17
 [3,]    3    8   13   18
 [4,]    4    9   14   19
 [5,]    5   10   15   20

 > beta
 [1] 10 20 30 40

 > sweep(data,MARGIN=2,beta,`*`)
      [,1] [,2] [,3] [,4]
 [1,]   10  120  330  640
 [2,]   20  140  360  680
 [3,]   30  160  390  720
 [4,]   40  180  420  760
 [5,]   50  200  450  800

我在 Python 中听说过关于 numpypandas 的令人兴奋的事情,而且它似乎有很多类似 R 的命令。使用这些库实现相同目标的最快方法是什么?实际数据有数百万行和大约 50 列。 beta 向量当然是符合数据的。

【问题讨论】:

  • 由于一些知识渊博的 pandas 用户可能没有安装 R,因此可以通过显示 sweep 的输入和输出来大大改善这个问题
  • 这个保证金是多少?文档不清楚只是清扫(即beta * data)之间有什么区别。
  • MARGIN表示是否对行上的列进行处理,MARGIN=2表示列,1表示行
  • 如果数字不是随机的,则更容易看到发生了什么。因此我的编辑。

标签: python arrays r numpy pandas


【解决方案1】:

这会更快吗?

t(t(data) * beta)

这里有一些其他很棒的答案与分析Multiply rows of matrix by vector?

最后回答您关于 numpy.使用此参考(搜索矩阵乘法) http://mathesaurus.sourceforge.net/r-numpy.html

【讨论】:

  • 是的,已编辑以包含对 numpy 中等效调用的引用。并建议我的代码作为速度问题的解决方法,因为扫描对于矩阵乘法来说很慢。 O.P 可以查看我的链接答案以查看运行时间。
【解决方案2】:

Pandas 也有一个 apply() 方法,适用于 R 的 sweep() 底层使用的方法。 (请注意,MARGIN 参数与许多 pandas 函数中的 axis 参数“等效”,除了 takes values 0 and 1 rather than 1 and 2)。

np.random.seed = 1    
beta = pd.Series(np.random.randn(5))    
data = pd.DataFrame(np.random.randn(20, 5))

您可以将 apply 与在每一行上调用的函数一起使用:

data.apply(lambda row: row * beta, axis=1)

注意:axis=0 将应用于每一列,这是默认设置,因为数据是按列存储的,因此按列操作更有效。

但是,在这种情况下,很容易使矢量化显着加快(并且更具可读性),只需按行相乘即可:

In [21]: data.apply(lambda row: row * beta, axis=1).head()
Out[21]:
          0         1         2         3         4
0 -0.024827 -1.465294 -0.416155 -0.369182 -0.649587
1  0.026433  0.355915 -0.672302  0.225446 -0.520374
2  0.042254 -1.223200 -0.545957  0.103864 -0.372855
3  0.086367  0.218539 -1.033671  0.218388 -0.598549
4  0.203071 -3.402876  0.192504 -0.147548 -0.726001

In [22]: data.mul(beta, axis=1).head()  # just show first few rows with head
Out[22]:
          0         1         2         3         4
0 -0.024827 -1.465294 -0.416155 -0.369182 -0.649587
1  0.026433  0.355915 -0.672302  0.225446 -0.520374
2  0.042254 -1.223200 -0.545957  0.103864 -0.372855
3  0.086367  0.218539 -1.033671  0.218388 -0.598549
4  0.203071 -3.402876  0.192504 -0.147548 -0.726001

注意:这比使用* 更强大/允许更多控制。

您可以在 numpy 中执行相同的操作(即此处为 data.values),或者直接相乘,这样会更快,因为它不担心数据对齐,或者使用 vectorize 而不是应用。

【讨论】:

  • 很好的答案。我现在正在使用这种方法并且有一个问题。您能否评论一下lambdaapply 中的使用?有什么理由比使用def 声明的函数更喜欢它?非常感谢。
  • 它只是一个匿名函数,没有理由喜欢它(除了令人愉悦/简洁的语法)!
【解决方案3】:

在 numpy 中,这个概念被称为“广播”。示例:

import numpy as np
x = np.random.random((4, 3))
x * np.array(range(4))[:, np.newaxis] # sweep along the rows
x + np.array(range(3))[np.newaxis, :] # sweep along the columns

【讨论】:

    猜你喜欢
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    • 2020-03-18
    • 2019-07-18
    相关资源
    最近更新 更多