복붙노트

[PYTHON] 팬더 DataFrame을 주황색 테이블로 변환

PYTHON

팬더 DataFrame을 주황색 테이블로 변환

나는 이것이 GitHub에 관한 이슈임을 이미 알고있다. 누구든지 팬더 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

해결법

  1. ==============================

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

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

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

    업데이트 : table2df를 추가하면 int 및 float에 numpy를 사용하여 df2table 성능이 크게 향상되었습니다.

    오렌지색 파이썬 스크립트 콜렉션에이 스크립트를 보관하십시오. 이제 오렌지 환경에서 판다를 갖출 수 있습니다.

    사용법 : a_pandas_dataframe = table2df (a_orange_table), a_orange_table = df2 테이블 (a_pandas_dataframe)

    참고 :이 스크립트는 Python 2.x에서만 작동하며 Python 3.x 호환 스크립트에 대한 @DustinTang의 대답을 참조하십시오.

    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)
    
  2. ==============================

    2.pandas DataFrame을 Orange Table로 변환하려면 열 유형을 지정하는 도메인을 구성해야합니다.

    pandas DataFrame을 Orange Table로 변환하려면 열 유형을 지정하는 도메인을 구성해야합니다.

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

    다음 코드는 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()])
    

    Map (str, row) 단계가 필요하므로 Orange는 데이터에 개별 기능의 값이 포함되어 있고 값 목록의 값 인덱스가 아니라는 것을 알고 있습니다.

  3. ==============================

    3.이 코드는 @TurtleIzzy for Python3에서 개정되었습니다.

    이 코드는 @TurtleIzzy for Python3에서 개정되었습니다.

    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)
    
  4. ==============================

    4.이 같은?

    이 같은?

    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의 생성자를 참조하십시오.

  5. from https://stackoverflow.com/questions/26320638/converting-pandas-dataframe-to-orange-table by cc-by-sa and MIT license