我有以下数据框架,
df = pd.DataFrame(np.random.randint(0,1000, (5,6)),
columns = pd.MultiIndex.from_product([['CPC', 'Conversions'], ['April', 'June', 'May']])).rename_axis(index = {None : 'idx'})
df
CPC Conversions
April June May April June May
idx
0 663 964 971 663 76 927
1 405 217 754 370 306 34
2 474 229 664 354 66 885
3 73 538 139 417 876 855
4 619 618 618 455 134 805
我想以正确的格式访问月份列级别,所以我这样做了
df.loc[:, (slice(None), ['April', 'May', 'June'])]
CPC Conversions CPC Conversions CPC Conversions
April April May May June June
idx
0 806 202 963 975 110 55
1 263 884 442 563 216 694
2 462 361 780 412 858 670
3 742 756 525 33 477 826
4 579 332 91 802 829 231
当我使用两个月而不是三个月(见下文)时,结果却很好,这很奇怪
df.loc[:, (slice(None), ['April', 'May'])]
CPC Conversions
April May April May
idx
0 856 619 180 593
1 64 403 929 80
2 973 285 803 967
3 769 405 701 267
4 940 368 863 717
谁能告诉我什么是错误的,这在我看来buggy
。
目前我正在做的是创建一个MultiIndex.from_product
(就像我用来创建这个例子一样)与有序的月份,并用它替换现有的列。但是,我不想这样做,因为其他列级别可能会随着时间的推移而改变。
这不是bug,只是意外:
>>> df.columns.levels
FrozenList([['CPC', 'Conversions'], ['April', 'June', 'May']])
>>> df.columns.codes
FrozenList([[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]])
>>> df.columns.is_monotonic
True
我们可以看到'April'的代码为0,'June'的代码为1,'May'的代码为2。
现在按秒级对数据帧进行切片:
# Your code (unordered codes)
>>> df.loc[:, (slice(None), ['April', 'May', 'June'])]
CPC Conversions CPC Conversions CPC Conversions
April April May May June June
...
,但是如果你根据有序的代码切片你的数据帧,它工作如预期:
>>> df.loc[:, (slice(None), ['April', 'June', 'May'])]
CPC Conversions
April June May April June May
...
检查一些属性:
>>> df.loc[:, (slice(None), ['April', 'May', 'June'])].columns.is_monotonic
False
>>> df.loc[:, (slice(None), ['April', 'June', 'May'])].columns.is_monotonic
True
>>> df.loc[:, (slice(None), ['April', 'May', 'June'])].columns.codes
FrozenList([[0, 1, 0, 1, 0, 1], [0, 0, 2, 2, 1, 1]])
>>> df.loc[:, (slice(None), ['April', 'June', 'May'])].columns.codes
FrozenList([[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]])
如果你在你的切片之后使用sort_index
,数据帧被排序为它的创建:
>>> df.loc[:, (slice(None), ['April', 'May', 'June'])].sort_index(axis=1)
CPC Conversions
April June May April June May
...
基于codes
排序MultiIndex
。
您可以使用df.reindex()
:
cols = ['April', 'May', 'June']
new_cols = df.columns.reindex(cols, level=1)
df.reindex(columns=new_cols[0])
不创建新变量:
df.reindex(columns=['April', 'May', 'June'], level=1)