Python 熊猫:使用现有索引和列标题创建多索引/组

Python 熊猫:使用现有索引和列标题创建多索引/组,python,pandas,pivot,Python,Pandas,Pivot,我试图将一个二维数据框转换成一个(或多或少)一维数据框,其中一个现有列用作第一级索引,列标题用作第二级索引 我一直在尝试.melt(),.groupby(),.transpose(),.MultiIndex(),.pivot()。。。所有这些都没有任何运气——我想主要是因为它们需要以某种我无法理解的方式结合在一起 设置: import pandas as pd from io import StringIO csv = StringIO(u''' AXIS A B

我试图将一个二维数据框转换成一个(或多或少)一维数据框,其中一个现有列用作第一级索引,列标题用作第二级索引

我一直在尝试
.melt()
.groupby()
.transpose()
.MultiIndex()
.pivot()
。。。所有这些都没有任何运气——我想主要是因为它们需要以某种我无法理解的方式结合在一起

设置:

import pandas as pd
from io import StringIO

csv = StringIO(u'''
AXIS    A       B       C       D
X       100     101     102     103 
Y       200     201     202     203
Z       300     301     302     303
''')

df = pd.read_csv(csv, delim_whitespace = True)
                Num
One     Two     
  X       A     100
  X       B     101
  X       C     102
  X       D     103
  Y       A     200
  Y       B     201
  Y       C     202
  Y       D     203
  Z       A     300
  Z       B     301
  Z       C     302
  Z       D     303
所需输出:

import pandas as pd
from io import StringIO

csv = StringIO(u'''
AXIS    A       B       C       D
X       100     101     102     103 
Y       200     201     202     203
Z       300     301     302     303
''')

df = pd.read_csv(csv, delim_whitespace = True)
                Num
One     Two     
  X       A     100
  X       B     101
  X       C     102
  X       D     103
  Y       A     200
  Y       B     201
  Y       C     202
  Y       D     203
  Z       A     300
  Z       B     301
  Z       C     302
  Z       D     303

提前感谢。

使用,
设置索引
堆栈
,和
重置索引

df.set_index('AXIS').stack().reset_index()
输出:

   AXIS level_1    0
0     X       A  100
1     X       B  101
2     X       C  102
3     X       D  103
4     Y       A  200
5     Y       B  201
6     Y       C  202
7     Y       D  203
8     Z       A  300
9     Z       B  301
10    Z       C  302
11    Z       D  303
         num
one two     
X   A    100
    B    101
    C    102
    D    103
Y   A    200
    B    201
    C    202
    D    203
Z   A    300
    B    301
    C    302
    D    303
此外,您还可以通过重命名列、重置索引等方式进行整理

df.set_index('AXIS').stack().reset_index().rename(columns={'AXIS':'one','level_1':'two',0:'num'}).set_index(['one','two'])
输出:

   AXIS level_1    0
0     X       A  100
1     X       B  101
2     X       C  102
3     X       D  103
4     Y       A  200
5     Y       B  201
6     Y       C  202
7     Y       D  203
8     Z       A  300
9     Z       B  301
10    Z       C  302
11    Z       D  303
         num
one two     
X   A    100
    B    101
    C    102
    D    103
Y   A    200
    B    201
    C    202
    D    203
Z   A    300
    B    301
    C    302
    D    303

正如您所怀疑的,诀窍在于组合正确的id和值变量

 pd.melt(df, id_vars=['AXIS'], value_vars=['A', 'B', 'C', 'D']).sort_values(['AXIS'])
我喜欢这个速度

i = df.AXIS.values
c = np.array(list('ABCD'))
v = np.column_stack([df[col].values for col in c])
idx = pd.MultiIndex.from_arrays(
    [i.repeat(c.size), np.tile(c, i.size)],
    names=['One', 'Two']
)
# Or this for brevity
# idx = pd.MultiIndex.from_product([i, c], names=['One', 'Two'])
pd.DataFrame(v.ravel(), idx, ['Num'])

         Num
One Two     
X   A    100
    B    101
    C    102
    D    103
Y   A    200
    B    201
    C    202
    D    203
Z   A    300
    B    301
    C    302
    D    303

艾伦,谢谢你,但是@ScottBoston's更干净一点。我会接受的。gnub-谢谢,但这是按照
['A','B','C','D']
的顺序排序的,而不是
['X','Y','Z']
@pshep123我已经添加了使用变量
AXIS对数据帧进行排序的功能。。。错过了一个非常简单的。非常感谢。谢谢@piRSquared-当你说“速度”时,你是说该方法比提供的其他答案更快(处理时间)?我在那里看到一个列表,并且总是对本地python感到畏缩。。。但这可能是一种不必要的反应。@pshep123这是一种不必要的反应。对于
循环,理解通常非常快,并且通常比等效的
快。。。。我测试了理解与df.iloc[:,1:]值的对比,并且理解+
np.column\u stack
要快得多。至少在较小的数据集上。我还没有试过更大的。简单而优雅!:)