我有按月份分组的预测数据。
原始数据帧如下:

>>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重新分配值。但是,我在过去曾在未分组的数据帧上使用过这种技术,而且它工作得很好。
如果这个问题已经在另一篇文章中得到了明确的回答,请提供链接。我搜索了一下,但找不到类似的东西。
编辑:
我找到了解决办法。通过按照列的排序顺序创建新的多索引数据帧来手动重新编制索引。我在下面发布了解决方案。

最佳答案

对包含日期字符串的列名进行排序,然后将其用作子集以按特定顺序返回列:

from datetime import datetime
df[sorted(df.columns, key=lambda x: datetime.strptime(x, '%m/%y'))]

python -  Pandas 对分组数据框中的列重新排序-LMLPHP
玩具数据:
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

python -  Pandas 对分组数据框中的列重新排序-LMLPHP
将多个索引DF分成两个,一个包含预测值,另一个包含剩余的DF
for_df = clean_table_grouped[['FOR']]
clean_table_grouped = clean_table_grouped.drop(['FOR'], axis=1, level=0)

预测:
for_df

python -  Pandas 对分组数据框中的列重新排序-LMLPHP
剩余DF
clean_table_grouped

python -  Pandas 对分组数据框中的列重新排序-LMLPHP
通过应用与预编辑的post中相同的过程对forecastDF中的列进行排序。
order = sorted(for_df['FOR'].columns.tolist(), key=lambda x: datetime.strptime(x, '%m/%y'))

通过对已排序的列的DF进行子集,使DF按相同的顺序排列。
for_df = for_df['FOR'][order]

将forecastlist与其自身连接,以创建类似多索引的列。
for_df = pd.concat([for_df, for_df], axis=1, keys=['FOR'])

最后,将它们加入到公共索引中。
clean_table_grouped.join(for_df)

python -  Pandas 对分组数据框中的列重新排序-LMLPHP

10-02 06:43
查看更多