我预测的数据是按月分组的。 原始数据框某事是这样的:
>>clean_table_grouped[0:5]
STYLE COLOR SIZE FOR
MONTH 01/17 10/16 11/16 12/16
0 ####### ###### #### 0.0 15.0 15.0 15.0
1 ####### ###### #### 0.0 15.0 15.0 15.0
2 ####### ###### #### 0.0 15.0 15.0 15.0
3 ####### ###### #### 0.0 15.0 15.0 15.0
4 ####### ###### #### 0.0 15.0 15.0 15.0
>>clean_table_grouped.ix[0:,"FOR"][0:5]
MONTH 01/17 10/16 11/16 12/16
0 0.0 15.0 15.0 15.0
1 0.0 15.0 15.0 15.0
2 0.0 15.0 15.0 15.0
3 0.0 15.0 15.0 15.0
4 0.0 15.0 15.0 15.0
我只想按以下方式重新排序这4列:
(保持数据帧的其余部分不受影响)
MONTH 10/16 11/16 12/16 01/17
0 15.0 15.0 15.0 0.0
1 15.0 15.0 15.0 0.0
2 15.0 15.0 15.0 0.0
3 15.0 15.0 15.0 0.0
4 15.0 15.0 15.0 0.0
我尝试的解决方案是按照以下帖子重新排序子集的列: How to change the order of DataFrame columns?
我通过抓住列列表并首先对其进行排序来解决这个问题
>>for_cols = clean_table_grouped.ix[:,"FOR"].columns.tolist()
>>for_cols.sort(key = lambda x: x[0:2]) #sort by month ascending
>>for_cols.sort(key = lambda x: x[-2:]) #then sort by year ascending
查询数据框工作正常
>>clean_table_grouped.ix[0:,"FOR"][for_cols]
MONTH 10/16 11/16 12/16 01/17
0 15.0 15.0 15.0 0.0
1 15.0 15.0 15.0 0.0
2 15.0 15.0 15.0 0.0
3 15.0 15.0 15.0 0.0
4 15.0 15.0 15.0 0.0
然而,当我尝试在原始表中设置值时,我得到一个" NaN"的表:
>>clean_table_grouped.ix[0:,"FOR"] = clean_table_grouped.ix[0:,"FOR"][for_cols]
>>clean_table_grouped.ix[0:,"FOR"]
MONTH 01/17 10/16 11/16 12/16
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
我也尝试过压缩以避免链式语法(.ix [] [])。 这避免了NaN,但是,它没有改变数据帧-__-
>>for_cols = zip(["FOR", "FOR", "FOR", "FOR"], for_cols)
>>clean_table_grouped.ix[0:,"FOR"] = clean_table_grouped.ix[0:,for_cols]
>>clean_table_grouped.ix[0:,"FOR"]
MONTH 01/17 10/16 11/16 12/16
0 0.0 15.0 15.0 15.0
1 0.0 15.0 15.0 15.0
2 0.0 15.0 15.0 15.0
3 0.0 15.0 15.0 15.0
4 0.0 15.0 15.0 15.0
我意识到我正在使用ix来重新分配价值观。但是,我过去曾使用过这种技术来处理没有分组的数据帧,并且工作得很好。
如果这个问题已在另一篇文章(以清除方式)中得到解答,请提供链接。我搜索但找不到任何类似的东西。
修改 我找到了解决方案。通过按列所需的顺序创建新的多索引数据框来手动重新索引。我在下面发布了解决方案。
答案 0 :(得分:1)
对包含日期字符串的列名进行排序,然后将其用作子集以按特定顺序返回列:
from datetime import datetime
df[sorted(df.columns, key=lambda x: datetime.strptime(x, '%m/%y'))]
玩具数据:
from datetime import datetime
np.random.seed(42)
cols = [['STYLE', 'COLOR', 'SIZE', 'FOR', 'FOR', 'FOR', 'FOR'],
['', '', '', '01/17', '10/16', '11/16', '12/16']]
tups = list(zip(*cols))
index = pd.MultiIndex.from_tuples(tups, names=[None, 'MONTH'])
clean_table_grouped = pd.DataFrame(np.random.randint(0, 100, (100, 7)),
index=np.arange(100), columns=index)
clean_table_grouped = clean_table_grouped.head()
clean_table_grouped
将多索引DF
拆分为两个,其中一个包含预测值,另一个包含剩余的DF
。
for_df = clean_table_grouped[['FOR']]
clean_table_grouped = clean_table_grouped.drop(['FOR'], axis=1, level=0)
预测DF
:
for_df
剩余DF
:
clean_table_grouped
通过应用与预编辑帖子相同的步骤对预测DF
中的列进行排序。
order = sorted(for_df['FOR'].columns.tolist(), key=lambda x: datetime.strptime(x, '%m/%y'))
通过对已排序的DF
列进行分组,使list
的顺序相同。
for_df = for_df['FOR'][order]
将预测DF
与自身连接起来,以创建类似于列的多索引。
for_df = pd.concat([for_df, for_df], axis=1, keys=['FOR'])
最后,将他们加入公共索引。
clean_table_grouped.join(for_df)
答案 1 :(得分:0)
我自己的解决方案基于以下帖子的第二个答案: How can I reorder multi-indexed dataframe columns at a specific level
非常......只需使用您想要的多索引创建一个新的数据帧。 多指标数据帧不支持尝试使用.ix,.loc,.iloc插入值。如果您希望完全更改列子集的值(而不仅仅是交换),那么Nickil的分离和重新连接表的解决方案绝对是可行的方法。但是,如果您只想交换列,则下面的工作完全正常。我选择这个作为Nickil解决方案的答案,因为这个解决方案对我来说效果更好,因为我除了'FOR'之外还有其他数据按月分组,它给了我更灵活地重新排序列。
首先,将列表存储在您想要的订单中:
>>reindex_list = ['STYLE','COLOR','SIZE','FOR'] #desired order
>>month_list = clean_table_grouped.ix[0:,"FOR"].columns.tolist()
>>month_list.sort(key = lambda x: x[0:2]) #sort by month ascending
>>month_list.sort(key = lambda x: x[-2:]) #sort by year ascending
然后创建一个压缩列表,其中样式,颜色,大小压缩为'','FOR'每个月都会压缩。像这样:
[('STYLE',''),('COLOR',''),..., ('FOR','10/16'), ('FOR','11/16'), ...]
这是一种自动执行的算法:
>>zip_list = []
>>
for i in reindex_list:
if i in ['FOR']:
for j in month_list:
if j != '':
zip_list.append(zip([i],[j])[0])
else:
zip_list.append(zip([i],[''])[0])
然后从刚刚压缩的元组列表中创建一个多索引:
>>multi_cols = pd.MultiIndex.from_tuples(zip_list, names=['','MONTH'])
最后,使用新的multiindex创建一个新的数据框:
>>clean_table_grouped_ordered = pd.DataFrame(clean_table_grouped, columns=multi_cols)
>>clean_table_grouped_ordered[0:5]
STYLE COLOR SIZE FOR
MONTH 10/16 11/16 12/16 01/17
#### #### ### 15.0 15.0 15.0 0.0
#### #### ### 15.0 15.0 15.0 0.0
#### #### ### 15.0 15.0 15.0 0.0
#### #### ### 15.0 15.0 15.0 0.0
#### #### ### 15.0 15.0 15.0 0.0
#### #### ### 15.0 15.0 15.0 0.0