我使用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。
任何人都可以解释为什么会发生此异常以及如何避免它?或者,也许有更好的方法,我想要做的就是控制我的透视数据框的列顺序。
答案 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]