Pandas: 使用现有索引和列创建 MultiIndex / groupby headers
Pandas: Create MultiIndex / groupby using existing index and column headers
我正在尝试获取二维数据框并将其转换为 (more-or-less) one-dimensional 数据框,其中现有列用作第一级索引和列headers作为二级索引。
我一直在尝试 .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
提前致谢。
使用,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
正如您所怀疑的那样,诀窍在于组合正确的 id 和 value 变量
pd.melt(df, id_vars=['AXIS'], value_vars=['A', 'B', 'C', 'D']).sort_values(['AXIS'])
#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
我喜欢这个速度
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
我正在尝试获取二维数据框并将其转换为 (more-or-less) one-dimensional 数据框,其中现有列用作第一级索引和列headers作为二级索引。
我一直在尝试 .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
提前致谢。
使用,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
正如您所怀疑的那样,诀窍在于组合正确的 id 和 value 变量
pd.melt(df, id_vars=['AXIS'], value_vars=['A', 'B', 'C', 'D']).sort_values(['AXIS'])
#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
我喜欢这个速度
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