代码之家  ›  专栏  ›  技术社区  ›  sacuL

使用melt后分类数据类型发生变化

  •  5
  • sacuL  · 技术社区  · 6 年前

    在回答中 this question ,使用后发现 melt 在pandas数据帧上,以前是有序分类数据类型的列变成 object . 这是故意的行为吗?

    注意:不是寻找解决方案,只是想知道这种行为是否有任何原因,或者它是否不是预期的行为。

    例子:

    df :

      Cat  L_1  L_2  L_3
    0   A    1    2    3
    1   B    4    5    6
    2   C    7    8    9
    
    df['Cat'] = pd.Categorical(df['Cat'], categories = ['C','A','B'], ordered=True)
    
    # As you can see `Cat` is a category
    >>> df.dtypes
    Cat    category
    L_1       int64
    L_2       int64
    L_3       int64
    dtype: object
    
    melted = df.melt('Cat')
    
    >>> melted
      Cat variable  value
    0   A      L_1      1
    1   B      L_1      4
    2   C      L_1      7
    3   A      L_2      2
    4   B      L_2      5
    5   C      L_2      8
    6   A      L_3      3
    7   B      L_3      6
    8   C      L_3      9
    

    Cat ,它变成了一个对象:

    >>> melted.dtypes
    Cat         object
    variable    object
    value        int64
    dtype: object
    

    这是有意的吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   BENY    6 年前

    source 代码。0.22.0(我的旧版本)

     for col in id_vars:
            mdata[col] = np.tile(frame.pop(col).values, K)
         mcolumns = id_vars + var_name + [value_name]
    

    它将返回数据类型对象 np.tile .

    它已在0.23.4中修复(在我更新 pandas

    df.melt('Cat')
    Out[6]: 
      Cat variable  value
    0   A      L_1      1
    1   B      L_1      4
    2   C      L_1      7
    3   A      L_2      2
    4   B      L_2      5
    5   C      L_2      8
    6   A      L_3      3
    7   B      L_3      6
    8   C      L_3      9
    df.melt('Cat').dtypes
    Out[7]: 
    Cat         category
    variable      object
    value          int64
    dtype: object
    

    更多信息如何修复:

    for col in id_vars:
        id_data = frame.pop(col)
        if is_extension_type(id_data): # here will return True , then become concat not np.tile
            id_data = concat([id_data] * K, ignore_index=True)
        else:
            id_data = np.tile(id_data.values, K)
        mdata[col] = id_data