我试图获取一个二维数据框并将其转换为(或多或少)一维数据框,其中现有列用作第一级索引,列标题为用作二级指数。
我一直在尝试.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
提前致谢。
答案 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_index
,stack
和reset_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'])