使用pandas创建多索引列的简单方法



很抱歉,我没有得到仍然存在的答案。我只是用相同的列名粘合了两个数据框架。

|    |   X |   Y |   X |   Y |
|---:|----:|----:|----:|----:|
|  0 |   1 |   3 |   9 |   7 |
|  1 |   2 |   4 |   8 |   6 |

我想要的是

|    |    FOO    |    BAR    |
|    |   X |   Y |   X |   Y |
|---:|----:|----:|----:|----:|
|  0 |   1 |   3 |   9 |   7 |
|  1 |   2 |   4 |   8 |   6 |

我尝试了pd.MultiIndex.from_product([c.columns, ['FOO', 'BAR']]),但这导致

MultiIndex([('X', 'FOO'),
('X', 'BAR'),
('Y', 'FOO'),
('Y', 'BAR'),
('X', 'FOO'),
('X', 'BAR'),
('Y', 'FOO'),
('Y', 'BAR')],
)

但是我需要

MultiIndex([('X', 'FOO'),
('Y', 'FOO'),
('X', 'BAR'),
('Y', 'BAR')],
)

这是一个MWE

#!/usr/bin/env python3
import pandas as pd
a = pd.DataFrame({'X': [1,2], 'Y': [3, 4]})
b = pd.DataFrame({'X': [9,8], 'Y': [7, 6]})
c = pd.concat([a, b], axis=1)
# throws a ValueError: Length mismatch: Expected axis has 4 elements, new values have 8 elements
c.columns = pd.MultiIndex.from_product([c.columns, ['FOO', 'BAR']])

在我concat()它们之前,对两个独立的数据框架做点什么会有帮助吗?

您可以简单地使用numpy.repeatpandas.MultiIndex添加额外的级别:

import numpy as np
extra = ['FOO', 'BAR']
c.columns = pd.MultiIndex.from_arrays([np.repeat(extra, len(c.columns)//len(extra)),
c.columns])

输出:

FOO    BAR   
X  Y   X  Y
0   1  3   9  7
1   2  4   8  6

NB。如果列被打乱,对列进行排序并使用np.tile代替:

c = c.sort_index(axis=1)
extra = ['FOO', 'BAR']
c.columns = pd.MultiIndex.from_arrays([np.tile(extra, len(c.columns)//len(extra)),
c.columns])

输出:

FOO BAR FOO BAR
X   X   Y   Y
0   1   9   3   7
1   2   8   4   6

使用pd.concat函数的keys参数

pd.concat([a, b], axis = 1, keys = ["FOO", "BAR"])

如果您正在使用numpy数组

import pandas as pd
import numpy as np
_names=['FOO','BAR','FOO','BAR']
_idx=['X','Y','X','Y']
X=np.random.rand(4,len(_names))
columns = pd.MultiIndex.from_arrays([_names, _idx])
df=pd.DataFrame(data=X, columns=columns)