2010-04-19 2 views
7

필자는 R에 data.frame을 가지고 있습니다. 많은 데이터 (125 개 배열의 유전자 발현 수준)가 있습니다. 파이썬에서 데이터를 사용하고 싶습니다. R의 무능함과 30 분짜리 일이라고 생각합니다.rpy2 : data.frame을 numpy 배열로 변환

다음 코드를 사용하고 싶습니다. 이 코드를 이해하려면 변수 path에로드 할 때 immgen이라는 변수가있는 데이터 세트의 전체 경로가 포함되어 있는지 확인하십시오. immgen이 개체 (Bioconductor ExpressionSet 개체)이고 exprs(immgen)이 125 개의 열 (실험) 및 수만 개의 행 (유전자라고 함)이있는 데이터 프레임을 반환한다는 것을 알고 있습니다.

import numpy as np 
import rpy2.robjects as robjects 
# ... some code to build path 
robjects.r("load('%s')"%path) # loads immgen 
e = robjects.r['data.frame']("exprs(immgen)") 
expression_data = np.array(e) 

이 코드를 실행 (이 분명하지 않다 이런 경우에,이 R 코드를 호출하는 robjects.r를 사용하여 파이썬 코드입니다)하지만, expression_data은 단순히 array([[1]])입니다. 다시 누가 알

In [40]: e._get_ncol() 
Out[40]: 1 

In [41]: e._get_nrow() 
Out[41]: 1 

그러나 :

나는 때문에 같은 것들에 eexprs()에 의해 생성 된 데이터 프레임을 표시하지 않음을 확신? e이 내 data.frame을 대표한다고해도 어레이로 바로 변환되지 않는다는 것은 충분히 공정 할 것입니다. 데이터 프레임에는 배열 (rownames 및 colnames)보다 더 많은 내용이 포함되어있어서 삶이 이렇게 쉬워서는 안됩니다 . 그러나 나는 아직도 변환을 수행하는 방법을 찾을 수 없다. 문서의 표제에 대한 나의 제한된 이해가 이것이 가능해야 함을 암시하지만, 문서는 저에게 너무 간결합니다.

누구든지 어떤 생각을하고 있습니까?

답변

4

'exprs (immgen)'이/matrix /를 반환하고 마지막 목표가 데이터를 매트릭스로 갖는 것이 왜 data.frame을 통해 진행됩니까?

NumPy와에 행렬을 전달하면 간단합니다 (심지어 복사본을 만들지 않고 만들 수 있습니다) : http://rpy.sourceforge.net/rpy2/doc-2.1/html/numpy.html#from-rpy2-to-numpy

이 단순성과 효율성 모두에서 플랫 파일에서 숫자 데이터의 텍스트 표현을 겪고의 제안을 이길한다 데이터 교환 방법.

당신은 bioconductor 클래스와 함께 일하게하는 것, 다음에 관심이있을 수 있습니다 http://pypi.python.org/pypi/rpy2-bioconductor-extensions/

+0

아하 네 말이 맞아. 매트릭스 야. 훌륭해, 고마워. 해결책은 분명해. 나는 할 수있어. e = np .array (robjects.r ('exprs (immgen)')) 이제 e는 내 부동 소수점 숫자가 모두 포함 된 숫자 배열입니다. 감사합니다. Laurent! 저는 bioC rpy2에 관심이 있지만 가져올 수 없습니다. 지원 목록에 대한 질문은 아마도 ... –

7

R에서 Python으로 데이터 프레임을 전송하는 것이 가장 간단하고 신뢰할 수있는 방법입니다.

먼저 R 바인딩을 통해 데이터를 교환하는 것은 불필요한 합병이라고 생각합니다. R은 데이터를 내보내는 간단한 방법을 제공합니다. 마찬가지로 NumPy는 데이터 가져 오기에 알맞은 방법을 제공합니다. 파일 형식은 여기서 필요한 유일한 공통 인터페이스입니다. 문서 (과 가치가 무엇인지에 대한 내 자신의 경험) loadtxt에 따르면

data(iris) 
iris$Species = unclass(iris$Species) 

write.table(iris, file="/path/to/my/file/np_iris.txt", row.names=F, sep=",") 

# now start a python session 
import numpy as NP 

fpath = "/path/to/my/file/np_iris.txt" 

A = NP.loadtxt(fpath, comments="#", delimiter=",", skiprows=1) 

# print(type(A)) 
# returns: <type 'numpy.ndarray'> 

print(A.shape) 
# returns: (150, 5) 

print(A[1:5,]) 
# returns: 
[[ 4.9  3.   1.4  0.2  1. ] 
    [ 4.7  3.2  1.3  0.2  1. ] 
    [ 4.6  3.1  1.5  0.2  1. ] 
    [ 5.   3.6  1.4  0.2  1. ]] 

은 기존의 데이터 가져 오기에 대한 선호되는 방법입니다.

또한 loadtxt 데이터 유형 튜플 각각의 열에 대한 하나 개의 튜플 항목 (인수 dtypes이다)에 전달할 수있다. 열 머리글을 건너 뛰려면 'skiprows = 1'을 사용하십시오 (loadtxt 행은 1에서 인덱싱되고 0 열부터 인덱싱 됨).

마지막으로, 내보내기 전에 데이터 프레임 인수를 정수 (실제로 요소의 기본 데이터 형식)로 변환했습니다. 'unclass'가이를 수행하는 가장 쉬운 방법 일 수 있습니다. 당신이 큰 데이터가있는 경우

(즉, 메모리에 전체 데이터 파일을로드하지 않으려는하지만 여전히 접근 할 필요가) NumPy와의 메모리 매핑 데이터 구조 ('memmap')는 좋은 선택이 될 것입니다 :

from tempfile import mkdtemp 
import os.path as path 

filename = path.join(mkdtemp(), 'tempfile.dat') 

# now create a memory-mapped file with shape and data type 
# based on original R data frame: 
A = NP.memmap(fpath, dtype="float32", mode="w+", shape=(150, 5)) 

# methods are ' flush' (writes to disk any changes you make to the array), and 'close' 
# to write data to the memmap array (acdtually an array-like memory-map to 
# the data stored on disk) 
A[:] = somedata[:] 
+1

감사합니다 더그! 이것은 내가 해결해 놓은 해결책이기도합니다. 결과 파일이 + 50MB가되는 유일한 문제는 괜찮습니다.하지만 어색한 느낌입니다! 나는 rpy2 바인딩이'array, colnames, rownames = from_df ("data.frame()"'. –

+1

의 경우 (큰 데이터) 함수를 작성하도록하고 싶습니다. NumPy의 메모리 맵핑 된 데이터를 사용할 것입니다. 구조체를 사용하여 RAM에 전체 내용을로드하는 것을 피할 수 있습니다. 예를 들어 답을 편집하십시오. – doug

관련 문제