Pandas:使用现有索引和列标题创建MultiIndex / groupby

时间:2017-05-18 18:40:19

标签: python pandas pivot

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

我一直在尝试.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

提前致谢。

4 个答案:

答案 0 :(得分:3)

我喜欢这个速度

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

答案 1 :(得分:2)

使用,set_indexstackreset_index

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

而且,你可以通过重命名列重置索引等来做一些内务管理......

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

输出:

         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

答案 2 :(得分:2)

#Using pd.melt to convert columns to rows.
pd.melt(df.rename(columns={'AXIS':'ONE'}),id_vars='ONE', var_name='TWO', value_name='Num').set_index(['ONE','TWO']).sort_index()
Out[28]: 
         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

答案 3 :(得分:1)

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

 pd.melt(df, id_vars=['AXIS'], value_vars=['A', 'B', 'C', 'D']).sort_values(['AXIS'])