带有catagorical列的数据框无法打印

时间:2016-02-02 12:18:13

标签: python python-3.x pandas

我使用Pandas DataFrame来管理一些结果数据。要在我的数据框架上实现“切片和切块”,我使用'pivot_table'功能。除此之外,要获得列的自定义排序,我将我的一个列转换为“分类”列。 我发现当我尝试打印数据框时会出现以下错误:

属性错误:'分类'对象没有属性'标记'

如果我更改了我的代码以使该列不是“分类”,那么它可以正常工作。但是我的透视结果有默认的(按字母顺序排列)列顺序。

以下是我的代码的缩减版本:

import pandas as pd

# Build data frame
data=[
    (1, 'ABC', '3M', 0.1), 
    (1, 'ABC', '1Y', 0.1), 
    (1, 'ABC', '2Y', 0.1), 
    (1, 'ABC', '3Y', 0.1), 
    (1, 'ABC', '5Y', 0.1), 
    (1, 'ABC', '7Y', 0.1), 
    (1, 'ABC', '10Y', 0.1), 
    (1, 'ABC', '15Y', 0.1), 
    (1, 'ABC', '20Y', 0.1), 
    (1, 'ABC', '25Y', 0.1), 
    (1, 'ABC', '30Y', 0.1), 
    (2, 'ABC', '3M', 0.1), 
    (2, 'ABC', '1Y', 0.1), 
    (2, 'ABC', '2Y', 0.1), 
    (2, 'ABC', '3Y', 0.1), 
    (2, 'ABC', '5Y', 0.1), 
    (2, 'ABC', '7Y', 0.1), 
    (2, 'ABC', '10Y', 0.1), 
    (2, 'ABC', '15Y', 0.1), 
    (2, 'ABC', '20Y', 0.1), 
    (2, 'ABC', '25Y', 0.1), 
    (2, 'ABC', '30Y', 0.1)]
df = pd.DataFrame(data=data, columns=('Ord', 'Name', 'label', 'Value'))

# Obtain a custom sorted list of lables
label_sort_order = {'3M': 1, '1Y': 2, '2Y': 3, '3Y': 4, '5Y': 5, '7Y': 6, '10Y': 7, '15Y': 8, '20Y': 9, '25Y': 10, '30Y': 11}
labels = label_sort_order.keys()
labels = sorted(labels, key=lambda label: label_sort_order[label])

# Convert label column to 'Categorical' so when pivoted it will respect the custom column ordering
df['label'] = pd.Categorical(df['label'], labels)
df_pivot = pd.pivot_table(df, index=['Name'], columns=['Ord', 'label'])

print(df_pivot) # Thows exception

我正在使用python 3.4.3并安装了pandas 0.16.2。

任何人都可以解释为什么会发生此异常以及如何避免它?或者,也许有更好的方法,我想要做的就是控制我的透视数据框的列顺序。

2 个答案:

答案 0 :(得分:0)

您可以使用reindex函数对多索引中任何级别的标签重新排序:

首先,我重复使用您的代码:

df = pd.DataFrame(data=data, columns=('Ord', 'Name', 'label', 'Value'))
label_sort_order = {'3M': 1, '1Y': 2, '2Y': 3, '3Y': 4, '5Y': 5, '7Y': 6, '10Y': 7, '15Y': 8, '20Y': 9, '25Y': 10, '30Y': 11}
labels = label_sort_order.keys()
labels = sorted(labels, key=lambda label: label_sort_order[label])

然后我转置以使用reindex函数:

df_pivot.transpose().reindex(labels, level='label')

更新reindex是pandas 0.17的新功能。你一定要考虑更新。

答案 1 :(得分:0)

您可以使用Ordered Categorical创建列src="rootname/ifmorefolders/ddslick.js"

label
# Obtain a custom sorted list of lables
label_sort_order = {'3M': 1, '1Y': 2, '2Y': 3, '3Y': 4, '5Y': 5, '7Y': 6, '10Y': 7, '15Y': 8, '20Y': 9, '25Y': 10, '30Y': 11}
print label_sort_order
{'3Y': 4, '5Y': 5, '1Y': 2, '2Y': 3, '3M': 1, '30Y': 11, '15Y': 8, '25Y': 10, '20Y': 9, '10Y': 7, '7Y': 6}

#swap keys and values in dictionary label_sort_order
swap_dict = dict((v,k) for k,v in label_sort_order.items())
print swap_dict
{1: '3M', 2: '1Y', 3: '2Y', 4: '3Y', 5: '5Y', 6: '7Y', 7: '10Y', 8: '15Y', 9: '20Y', 10: '25Y', 11: '30Y'}

#create new Series - is sorted by keys converted to index
s = pd.Series(swap_dict)
print s
1      3M
2      1Y
3      2Y
4      3Y
5      5Y
6      7Y
7     10Y
8     15Y
9     20Y
10    25Y
11    30Y
dtype: object

#get sorted values of Series s
print s.values
['3M' '1Y' '2Y' '3Y' '5Y' '7Y' '10Y' '15Y' '20Y' '25Y' '30Y']
#add parameter ordered=True
print pd.Categorical(df['label'], categories=s.values, ordered=True)
[3M, 1Y, 2Y, 3Y, 5Y, ..., 10Y, 15Y, 20Y, 25Y, 30Y]
Length: 22
Categories (11, object): [3M < 1Y < 2Y < 3Y ... 15Y < 20Y < 25Y < 30Y]