将Pandas DataFrame转换为Orange Table

时间:2014-10-12 00:29:38

标签: python pandas dataframe orange

我注意到这是issue on GitHub already。有没有人有任何将Pandas DataFrame转换为Orange Table的代码?

明确地说,我有下表。

       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

7 个答案:

答案 0 :(得分:17)

Orange包的文档并未涵盖所有细节。根据{{​​1}},Table._init__(Domain, numpy.ndarray)仅适用于intfloat

他们确实应该为lib_kernel.cpp或至少pandas.DataFrames支持提供C级界面。

更新:通过将numpy用于int和float,大大提高了numpy.dtype("str")table2df的性能。

将这段脚本保存在橙色python脚本集合中,现在你在橙色环境中配备了pandas。

用法df2tablea_pandas_dataframe = table2df( a_orange_table )

注意:此脚本仅适用于Python 2.x,请参阅@DustinTang的answer以获取Python 3.x兼容脚本。

a_orange_table = df2table( a_pandas_dataframe )

答案 1 :(得分:6)

from Orange.data.pandas_compat import table_from_frame,table_to_frame
df= table_to_frame(in_data)
#here you go
out_data = table_from_frame(df)

基于Creo的答案

答案 2 :(得分:2)

为了将pandas DataFrame转换为Orange Table,您需要构建一个指定列类型的域。

对于连续变量,您只需要提供变量的名称,但对于离散变量,您还需要提供所有可能值的列表。

以下代码将为您的DataFrame构建一个域并将其转换为Orange Table:

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 :(得分:2)

此代码从@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 :(得分:1)

这样的东西?

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

Orange中的列将获得通用名称(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 :(得分:0)

下面是a closed issue on github的答案

from Orange.data.pandas_compat import table_from_frame
out_data = table_from_frame(df)

其中df是您的dataFrame。到目前为止,我只注意到如果数据源不是100%干净且未达到所需的ISO标准,则需要手动定义一个域来处理日期。

我意识到这是一个古老的问题,与第一次提出时相比有很大的变化-但是这个问题在有关该主题的google搜索结果中排在首位。

答案 6 :(得分:0)

table_from_frame(在Python 3中可用)不允许定义类列,因此,生成的表不能直接用于训练分类模型。我调整了table_from_frame函数,以便可以定义类列。请注意,应将类名作为附加参数来提供。

"""Pandas DataFrame↔Table conversion helpers"""
import numpy as np
import pandas as pd
from pandas.api.types import (
    is_categorical_dtype, is_object_dtype,
    is_datetime64_any_dtype, is_numeric_dtype,
)

from Orange.data import (
    Table, Domain, DiscreteVariable, StringVariable, TimeVariable,
    ContinuousVariable,
)

__all__ = ['table_from_frame', 'table_to_frame']


def table_from_frame(df,class_name, *, force_nominal=False):
    """
    Convert pandas.DataFrame to Orange.data.Table

    Parameters
    ----------
    df : pandas.DataFrame
    force_nominal : boolean
        If True, interpret ALL string columns as nominal (DiscreteVariable).

    Returns
    -------
    Table
    """

    def _is_discrete(s):
        return (is_categorical_dtype(s) or
                is_object_dtype(s) and (force_nominal or
                                        s.nunique() < s.size**.666))

    def _is_datetime(s):
        if is_datetime64_any_dtype(s):
            return True
        try:
            if is_object_dtype(s):
                pd.to_datetime(s, infer_datetime_format=True)
                return True
        except Exception:  # pylint: disable=broad-except
            pass
        return False

    # If df index is not a simple RangeIndex (or similar), put it into data
    if not (df.index.is_integer() and (df.index.is_monotonic_increasing or
                                       df.index.is_monotonic_decreasing)):
        df = df.reset_index()

    attrs, metas,calss_vars = [], [],[]
    X, M = [], []

    # Iter over columns
    for name, s in df.items():
        name = str(name)
        if name == class_name:
            discrete = s.astype('category').cat
            calss_vars.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))
            X.append(discrete.codes.replace(-1, np.nan).values)
        elif _is_discrete(s):
            discrete = s.astype('category').cat
            attrs.append(DiscreteVariable(name, discrete.categories.astype(str).tolist()))
            X.append(discrete.codes.replace(-1, np.nan).values)
        elif _is_datetime(s):
            tvar = TimeVariable(name)
            attrs.append(tvar)
            s = pd.to_datetime(s, infer_datetime_format=True)
            X.append(s.astype('str').replace('NaT', np.nan).map(tvar.parse).values)
        elif is_numeric_dtype(s):
            attrs.append(ContinuousVariable(name))
            X.append(s.values)
        else:
            metas.append(StringVariable(name))
            M.append(s.values.astype(object))

    return Table.from_numpy(Domain(attrs, calss_vars, metas),
                            np.column_stack(X) if X else np.empty((df.shape[0], 0)),
                            None,
                            np.column_stack(M) if M else None)