2014-10-12 4 views
8

이 메시지는 issue on GitHub already입니다. 누구든지 팬더 DataFrame을 오렌지 테이블로 변환하는 코드가 있습니까?팬더 데이터 프레임을 주황색으로 변환 표

명시 적으로 다음 표가 있습니다.

 user hotel star_rating user home_continent gender 
0   1  39   4.0  1    2 female 
1   1  44   3.0  1    2 female 
2   2  63   4.5  2    3 female 
3   2  2   2.0  2    3 female 
4   3  26   4.0  3    1 male 
5   3  37   5.0  3    1 male 
6   3  63   4.5  3    1 male 
+0

오렌지 형식은 어려운 OUPUT에 보이지 않는 , 너 뭐 해봤 니? – EdChum

+0

그래서 데이터가 *로 저장되는 방식을 이해할 수있었습니다.탭 파일을 포함하지만, 팬더 DataFrame을 오렌지 테이블로 변환 할 수있는 함수 또는 일련의 호출이 있습니까? (사이드 코멘트 : 데이터가 외부 파일에 저장되는 방법에 대해 페이지가 이야기하는 방법은 재미 있지만 파일을 저장 /로드하는 방법에 대해서는 언급하지 않습니다.) 개인적으로 오렌지가 잘 문서화되어 있지 않다고 생각합니다. – hlin117

+0

저장하는 워크 플로우 Pandas의 테이블을 파일로 저장 한 다음 Orange에서 파일을 가져옵니다. 또는 너무 많은 kludge? 필드 데이터 형식이 제대로 전달되지 않을 수도 있습니다. – BKay

답변

17

오렌지 패키지 설명서에 모든 세부 사항이 나와 있지 않습니다. Table._init__(Domain, numpy.ndarray)은 및 float에 대해서만 lib_kernel.cpp에 따라 작동합니다.

그들은 실제로 pandas.DataFrames, 또는 적어도 numpy.dtype("str") 지원을위한 C 레벨 인터페이스를 제공해야합니다.

업데이트 : int에 numpy를 사용하고 float을 사용하면 table2df, df2table 성능이 크게 향상됩니다.

주황색 환경에서 팬더가 장착 된 주황색 파이썬 스크립트 콜렉션에이 스크립트를 보관하십시오.

사용 : a_pandas_dataframe = table2df(a_orange_table), a_orange_table = df2table(a_pandas_dataframe)

:이 스크립트는 파이썬 2.x에서 작동 파이썬 3.x를 호환 스크립트 @DustinTang의 answer를 참조하십시오.

import pandas as pd 
import numpy as np 
import Orange 

#### For those who are familiar with pandas 
#### Correspondence: 
#### value <-> Orange.data.Value 
####  NaN <-> ["?", "~", "."] # Don't know, Don't care, Other 
#### dtype <-> Orange.feature.Descriptor 
####  category, int <-> Orange.feature.Discrete # category: > pandas 0.15 
####  int, float <-> Orange.feature.Continuous # Continuous = core.FloatVariable 
####             # refer to feature/__init__.py 
####  str <-> Orange.feature.String 
####  object <-> Orange.feature.Python 
#### DataFrame.dtypes <-> Orange.data.Domain 
#### DataFrame.DataFrame <-> Orange.data.Table = Orange.orange.ExampleTable 
####        # You will need this if you are reading sources 

def series2descriptor(d, discrete=False): 
    if d.dtype is np.dtype("float"): 
     return Orange.feature.Continuous(str(d.name)) 
    elif d.dtype is np.dtype("int"): 
     return Orange.feature.Continuous(str(d.name), number_of_decimals=0) 
    else: 
     t = d.unique() 
     if discrete or len(t) < len(d)/2: 
      t.sort() 
      return Orange.feature.Discrete(str(d.name), values=list(t.astype("str"))) 
     else: 
      return Orange.feature.String(str(d.name)) 


def df2domain(df): 
    featurelist = [series2descriptor(df.icol(col)) for col in xrange(len(df.columns))] 
    return Orange.data.Domain(featurelist) 


def df2table(df): 
    # It seems they are using native python object/lists internally for Orange.data types (?) 
    # And I didn't find a constructor suitable for pandas.DataFrame since it may carry 
    # multiple dtypes 
    # --> the best approximate is Orange.data.Table.__init__(domain, numpy.ndarray), 
    # --> but the dtype of numpy array can only be "int" and "float" 
    # --> * refer to src/orange/lib_kernel.cpp 3059: 
    # --> * if (((*vi)->varType != TValue::INTVAR) && ((*vi)->varType != TValue::FLOATVAR)) 
    # --> Documents never mentioned >_< 
    # So we use numpy constructor for those int/float columns, python list constructor for other 

    tdomain = df2domain(df) 
    ttables = [series2table(df.icol(i), tdomain[i]) for i in xrange(len(df.columns))] 
    return Orange.data.Table(ttables) 

    # For performance concerns, here are my results 
    # dtndarray = np.random.rand(100000, 100) 
    # dtlist = list(dtndarray) 
    # tdomain = Orange.data.Domain([Orange.feature.Continuous("var" + str(i)) for i in xrange(100)]) 
    # tinsts = [Orange.data.Instance(tdomain, list(dtlist[i]))for i in xrange(len(dtlist))] 
    # t = Orange.data.Table(tdomain, tinsts) 
    # 
    # timeit list(dtndarray) # 45.6ms 
    # timeit [Orange.data.Instance(tdomain, list(dtlist[i])) for i in xrange(len(dtlist))] # 3.28s 
    # timeit Orange.data.Table(tdomain, tinsts) # 280ms 

    # timeit Orange.data.Table(tdomain, dtndarray) # 380ms 
    # 
    # As illustrated above, utilizing constructor with ndarray can greatly improve performance 
    # So one may conceive better converter based on these results 


def series2table(series, variable): 
    if series.dtype is np.dtype("int") or series.dtype is np.dtype("float"): 
     # Use numpy 
     # Table._init__(Domain, numpy.ndarray) 
     return Orange.data.Table(Orange.data.Domain(variable), series.values[:, np.newaxis]) 
    else: 
     # Build instance list 
     # Table.__init__(Domain, list_of_instances) 
     tdomain = Orange.data.Domain(variable) 
     tinsts = [Orange.data.Instance(tdomain, [i]) for i in series] 
     return Orange.data.Table(tdomain, tinsts) 
     # 5x performance 


def column2df(col): 
    if type(col.domain[0]) is Orange.feature.Continuous: 
     return (col.domain[0].name, pd.Series(col.to_numpy()[0].flatten())) 
    else: 
     tmp = pd.Series(np.array(list(col)).flatten()) # type(tmp) -> np.array(dtype=list (Orange.data.Value)) 
     tmp = tmp.apply(lambda x: str(x[0])) 
     return (col.domain[0].name, tmp) 

def table2df(tab): 
    # Orange.data.Table().to_numpy() cannot handle strings 
    # So we must build the array column by column, 
    # When it comes to strings, python list is used 
    series = [column2df(tab.select(i)) for i in xrange(len(tab.domain))] 
    series_name = [i[0] for i in series] # To keep the order of variables unchanged 
    series_data = dict(series) 
    print series_data 
    return pd.DataFrame(series_data, columns=series_name) 
+0

매우 철저한 응답을 주신 것 같습니다. 감사합니다! 이 기능은 모든 Orange 테이블/Panda DataFrame에서 작동합니까? – hlin117

+0

잘하면 네, 내 자신의 데이터 세트를 테스트했지만 더 많은 테스트가 필요할 수 있습니다. – TurtleIzzy

+0

이것은 Python3과 Orange3에서 작동하지 않았습니다. 그러나 고마워! –

1

이와 비슷한?

table = Orange.data.Table(df.as_matrix()) 

오렌지색 열에는 일반 이름 (a1, a2 ...)이 표시됩니다. 데이터 프레임에서 이름과 유형을 복사하려면 데이터 프레임에서 Orange.data.Domain 객체 (http://docs.orange.biolab.si/reference/rst/Orange.data.domain.html#Orange.data.Domain.init)를 생성하고 위의 첫 번째 인수로 전달합니다.

http://docs.orange.biolab.si/reference/rst/Orange.data.table.html의 생성자를 참조하십시오.

+0

이것을 시도 할 때 도메인 오류가 발생합니다. "TypeError : 생성자에 대한 인수가 잘못되었습니다 (도메인 또는 예제 또는 둘 다 예상 됨)." 도메인에 추가 할 수있는 코드를 제공 할 수 있습니까? – hlin117

+1

'df = DataFrame ({ "A": [1, 2, 3, 4], "B": [8, 7, 6, 5]})'이라고합시다. 'domain = Orange.data.Domain ([df.columns에 이름에 대한 Orange.feature.Continuous (이름)]') 그리고'table = Orange.data.Table (domain, df.as_matrix())를 사용하여 도메인을 구성하십시오. ' – JanezD

+0

오, 작동하지 않는다면 : 데이터 프레임은 어떻게 생겼습니까? 'df.as_matrix(). dtype'가'object'이면 Orange는 그것을 받아들이지 않습니다. 범주 형 데이터를 인덱스로 변환해야합니다. – JanezD

2

팬더 DataFrame을 주황색 테이블로 변환하려면 열 유형을 지정하는 도메인을 구성해야합니다.

연속 변수의 경우 변수 이름 만 입력하면되지만 이산 변수의 경우 가능한 모든 값의 목록을 제공해야합니다.

다음 코드는 DataFrame에 대한 도메인을 구성하고 오렌지 테이블로 변환됩니다

import numpy as np 
from Orange.feature import Discrete, Continuous 
from Orange.data import Domain, Table 
domain = Domain([ 
    Discrete('user', values=[str(v) for v in np.unique(df.user)]), 
    Discrete('hotel', values=[str(v) for v in np.unique(df.hotel)]), 
    Continuous('star_rating'), 
    Discrete('user', values=[str(v) for v in np.unique(df.user)]), 
    Discrete('home_continent', values=[str(v) for v in np.unique(df.home_continent)]), 
    Discrete('gender', values=['male', 'female'])], False) 
table = Table(domain, [map(str, row) for row in df.as_matrix()]) 

오렌지 데이터가 분리 된 기능의 값을 가지는 것을 알 수 있도록지도 (STR, 행) 단계가 필요하다 (값 목록의 값 색인이 아님).

+0

위대한 작품! 나는 그것을 테스트했고 성별로 테이블을 정렬 할 수있는 것처럼 보였으므로 대부분의 다른 테이블 함수가 작동한다고 가정합니다. – hlin117

+0

ID가되는 기능을 설명하려면 다른 데이터 유형이 있습니까? (예, 사용자 ID) – hlin117

2

이 코드는 @TurtleIzzy for Python3에서 개정되었습니다. http://docs.orange.biolab.si/reference/rst/Orange.data.formats.html는 또한 데이터 유형을 CSV 파일을 가져오고 추측 지원 :

import numpy as np 
from Orange.data import Table, Domain, ContinuousVariable, DiscreteVariable 


def series2descriptor(d): 
    if d.dtype is np.dtype("float") or d.dtype is np.dtype("int"): 
     return ContinuousVariable(str(d.name)) 
    else: 
     t = d.unique() 
     t.sort() 
     return DiscreteVariable(str(d.name), list(t.astype("str"))) 

def df2domain(df): 
    featurelist = [series2descriptor(df.iloc[:,col]) for col in range(len(df.columns))] 
    return Domain(featurelist) 

def df2table(df): 
    tdomain = df2domain(df) 
    ttables = [series2table(df.iloc[:,i], tdomain[i]) for i in range(len(df.columns))] 
    ttables = np.array(ttables).reshape((len(df.columns),-1)).transpose() 
    return Table(tdomain , ttables) 

def series2table(series, variable): 
    if series.dtype is np.dtype("int") or series.dtype is np.dtype("float"): 
     series = series.values[:, np.newaxis] 
     return Table(series) 
    else: 
     series = series.astype('category').cat.codes.reshape((-1,1)) 
     return Table(series) 
관련 문제