오렌지 패키지 설명서에 모든 세부 사항이 나와 있지 않습니다. 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)
오렌지 형식은 어려운 OUPUT에 보이지 않는 , 너 뭐 해봤 니? – EdChum
그래서 데이터가 *로 저장되는 방식을 이해할 수있었습니다.탭 파일을 포함하지만, 팬더 DataFrame을 오렌지 테이블로 변환 할 수있는 함수 또는 일련의 호출이 있습니까? (사이드 코멘트 : 데이터가 외부 파일에 저장되는 방법에 대해 페이지가 이야기하는 방법은 재미 있지만 파일을 저장 /로드하는 방법에 대해서는 언급하지 않습니다.) 개인적으로 오렌지가 잘 문서화되어 있지 않다고 생각합니다. – hlin117
저장하는 워크 플로우 Pandas의 테이블을 파일로 저장 한 다음 Orange에서 파일을 가져옵니다. 또는 너무 많은 kludge? 필드 데이터 형식이 제대로 전달되지 않을 수도 있습니다. – BKay