对不起,标题太乱了,我不知道该如何措辞好。
假设我有一个表,其中前三列是foo bar和baz。然后是一些任意列。我想对表进行操作,以使这些任意列都折叠在名为num的列下。
一个例子使这一点更清楚
foo, bar, baz, 100, 101, 102, 103, 104,
1, 1, 1, 10, 11, 12, 13, 14,
1, 1, 2, 15, 16, 17, 18, 19,
1, 2, 1, 20, 21, 22, 23, 24,
此输入应转置为:
num, foo, bar, baz, value,
100, 1, 1, 1, 10,
100, 1, 1, 2, 15,
100, 1, 2, 1, 20,
101, 1, 1, 1, 11,
101, 1, 1, 2, 16,
101, 1, 2, 1, 21,
102, 1, 1, 1, 12,
102, 1, 1, 2, 17,
102, 1, 2, 1, 22,
...
我写了一个自定义的Python解决方案来做到这一点。并不困难,但是我觉得这是在重新发明轮子。
是否有一种方法可以通过类似pandas之类的库或其他一些表操作模块来实现?
答案 0 :(得分:6)
使用pandas.melt
:
res = pd.melt(df, id_vars=['foo', 'bar', 'baz'])
print(res)
foo bar baz variable value
0 1 1 1 100 10
1 1 1 2 100 15
2 1 2 1 100 20
3 1 1 1 101 11
4 1 1 2 101 16
5 1 2 1 101 21
6 1 1 1 102 12
7 1 1 2 102 17
8 1 2 1 102 22
9 1 1 1 103 13
10 1 1 2 103 18
11 1 2 1 103 23
12 1 1 1 104 14
13 1 1 2 104 19
14 1 2 1 104 24
答案 1 :(得分:2)
cols = np.concatenate([['num'], df.columns[:3], ['value']])
pd.DataFrame([
[a, b, c, d, e]
for b, c, d, *x in df.values
for a, e in zip(df.columns[3:], x)
]).set_axis(cols, axis=1, inplace=False).sort_values('num')
num foo bar baz value
0 100 1 1 1 10
5 100 1 1 2 15
10 100 1 2 1 20
1 101 1 1 1 11
6 101 1 1 2 16
11 101 1 2 1 21
2 102 1 1 1 12
7 102 1 1 2 17
12 102 1 2 1 22
3 103 1 1 1 13
8 103 1 1 2 18
13 103 1 2 1 23
4 104 1 1 1 14
9 104 1 1 2 19
14 104 1 2 1 24
答案 2 :(得分:2)
您可以对set_index
,stack
和某些列重命名使用数据帧重塑:
(df.set_index(['foo','bar','baz'])
.stack()
.reset_index(name='value')
.rename(columns={'level_3':'num'}))
输出:
foo bar baz num value
0 1 1 1 100 10
1 1 1 1 101 11
2 1 1 1 102 12
3 1 1 1 103 13
4 1 1 1 104 14
5 1 1 2 100 15
6 1 1 2 101 16
7 1 1 2 102 17
8 1 1 2 103 18
9 1 1 2 104 19
10 1 2 1 100 20
11 1 2 1 101 21
12 1 2 1 102 22
13 1 2 1 103 23
14 1 2 1 104 24
答案 3 :(得分:0)
如上所述,pandas.melt是最好的方法!
import pandas as pd
import numpy as np
#Create the dataframe
df = pd.DataFrame({'foo' : np.random.randint(low = 0, high=5, size = 3), 'bar' :
np.random.randint(low = 0, high=5, size = 3),'baz' :
np.random.randint(low = 0, high=5, size = 3)})
for i in range(100,105):
df['%d'%i] = np.random.randint(low = 10, high=20, size = 3)
print(df)
foo bar baz 100 101 102 103 104
0 2 1 4 16 14 13 16 11
1 3 0 4 11 17 12 15 18
2 4 1 1 13 15 11 18 17
现在,主要功能是:
pd.melt(frame=df, id_vars= ['foo', 'bar', 'baz'], value_vars= ['%d'%i for i in
range(100,105)])
#output
foo bar baz variable value
0 2 1 4 100 16
1 3 0 4 100 11
2 4 1 1 100 13
3 2 1 4 101 14
4 3 0 4 101 17
5 4 1 1 101 15
6 2 1 4 102 13
7 3 0 4 102 12
8 4 1 1 102 11
9 2 1 4 103 16
10 3 0 4 103 15
11 4 1 1 103 18
12 2 1 4 104 11
13 3 0 4 104 18
14 4 1 1 104 17