rpy2与标准R矩阵之间的差异

时间:2016-06-11 00:38:24

标签: r python-3.x memory matrix rpy2

我的目标

所以我尝试使用normalize_quantiles包中的preprocessCore包在python3脚本中调用R-3.2.1 R包(rpy2)中的require(preprocessCore); all <- data.matrix(read.table("data_table.txt",sep="\t",header=TRUE)); all[,6:57]=normalize.quantiles(all[,6:57]); write.table(all,"QN_data_table.txt",sep="\t",row.names=FALSE); 函数巨大的矩阵(10 gb +文件)。我几乎无限的记忆。当我使用以下内容通过R本身运行它时,我能够完成规范化并打印输出:

rpy2

我试图将它构建成一个python脚本,该脚本也使用matrix = sample_list # My 2-d python array containing the data. v = robjects.FloatVector([ element for col in matrix for element in col ]) m = robjects.r['matrix'](v, ncol = len(matrix), byrow=False) print("Performing quantile normalization.") Rnormalized_matrix = preprocessCore.normalize_quantiles(m) norm_matrix = np.array(Rnormalized_matrix) return header, pos_list, norm_matrix python包执行其他操作,但我在构建矩阵的方式上遇到了麻烦。一个例子如下:

rpy2.rinterface.RRuntimeError: Error: cannot allocate vector of size 9.7 Gb

问题

这适用于较小的文件,但是当我在我的大文件上运行时,它会因错误而死:matrix = sample_list # My 2-d python array of data. m_count = 1 m = robjects.r['matrix'](0.0, ncol=len(matrix), nrow=len(matrix[0])) for samp in matrix: i_count = 1 for entry in samp: m.rx[i_count, m_count] = entry # Assign the data to the element. i_count += 1 m_count += 1 print("Performing quantile normalization.") Rnormalized_matrix = preprocessCore.normalize_quantiles(m) norm_matrix = np.array(Rnormalized_matrix) return header, pos_list, norm_matrix

我知道R的向量的最大大小是8 Gb,这解释了为什么抛出上述错误。 rpy2 docs说:

  

&#34; Matrix是Array的一个特例。与数组一样,必须记住这只是一个具有维度属性(行数,列数)的向量。&#34;

我有点想知道它是如何严格遵守的,所以我改变了我的代码来初始化我想要的大小的矩阵然后迭代并将元素分配给值:

url = 'http://www.achema.de/de/ausstellung/aussteller-und-produkte.html'

driver.get(url)

resultsBox = driver.find_element_by_css_selector('div[id="ix_result"]')

for tr in resultsBox.find_elements_by_tag_name('tr'):
    link = tr.find_element_by_tag_name('a')
    link.click()

    # I've also tried:
    # ActionChains(driver).move_to_element(link).click(link).perform()

同样,这适用于较小的文件,但崩溃时的错误与之前相同。

所以我的问题是什么是允许在R中分配巨大矩阵的根本差异但是会导致rpy出现问题?我需要采用不同的方式来解决这个问题吗?我应该把它吸干并用R做吗?还是有办法规避我遇到的问题?

1 个答案:

答案 0 :(得分:1)

从根本上说,R是一种功能语言。这意味着在进行R

m[i, j] <- 123

正在发生的事情就像是

assign_to_cell <- `[<-`
m <- assign_to_cell(m, i, j, 123)

参数按值传递。

这意味着应返回一个新的矩阵m,其中(i,j)的单元格包含新值。使用每个赋值制作m的副本效率会相当低,尤其是在遇到大型对象时,所以R解释器有一个很好的技巧(有关详细信息,请参阅R&C的C源代码):将表达式的左侧与表达式的右侧进行比较,如果对象相同,则解释器将知道副本是不必要的,并且可以进行修改&#34;就位&#34;。

现在使用rpy2还需要考虑另外两点:虽然Python(大多数)通过引用传递参数,但嵌入式R引擎无法知道Python表达式左侧发生了什么。

表达式

m.rx[i_count, m_count] = entry 

忠实地建立一个R调用,如

m <- assign_to_cell(m, i, j, entry)

但是能够让R在表达式左侧向前看失去。结果是制作了m的副本。随着每次修改。

然而,rpy2使得将R中定义的向量,矩阵和数组移动到Python的传递引用世界变得容易。例如,这些R对象可以别名为相应的numpy个对象(使用asarra - 请参阅  http://rpy.sourceforge.net/rpy2/doc-2.0/html/numpy.html#low-level-interface)。记住R数组是按列主顺序,也可以计算索引并跳过别名到numpy数组并使用以下内容修改单元格:

m[idx] = entry 

注意:

我认为,如果我记得正确的话,由R指数为32位整数引起的对8Gb的限制在几年前被解除了。 你可能没有比你想象的更少的无限记忆。系统上的物理内存并不一定意味着可以将所有内容分配到一个连续的块中。