我不确定我的问题是否有特定的名字(我记得听过一次讲课,老师说其中一部分知识知道事物的名字)。
无论如何,我正在使用一些旧系统,并且我的数据输出如下:
df = pd.DataFrame({'Shop' : [1,2,3,4,5,6,7,8,9,10],'Week 1' : [15,25,11,22,0,-1,15,11,76,62],'Week 2' : [5,44,55,21,12,51,-10,25,81,46]})
print(df)
Shop Week 1 Week 2
0 1 15 5
1 2 25 44
2 3 11 55
3 4 22 21
4 5 0 12
5 6 -1 51
6 7 15 -10
7 8 11 25
8 9 76 81
9 10 62 46
在这种情况下,周号应该是观察值,而数字是应该分配给它的值。
我想做的是以下事情。
转置DF,但将索引保留为Shop。 将每个实例变成一个观察值,因此仅以前两个商店为例:
Shop Week Hour
0 1 1 15
1 1 2 5
2 2 1 25
3 2 2 44
实现这一目标的最Python方式是什么?在相对中等大小的df上(500行52周)
答案 0 :(得分:3)
使用wide_to_long
pd.wide_to_long(df,'Week ',i='Shop',j='week')
Out[770]:
Week
Shop week
1 1 15
2 1 25
3 1 11
4 1 22
5 1 0
6 1 -1
7 1 15
8 1 11
9 1 76
10 1 62
1 2 5
2 2 44
3 2 55
4 2 21
5 2 12
6 2 51
7 2 -10
8 2 25
9 2 81
10 2 46
#pd.wide_to_long(df,'Week ',i='Shop',j='week').sort_index(level=0).reset_index().rename(columns={'Week ':'Hour'})
答案 1 :(得分:2)
您可以先重命名列pd.melt
,然后重命名sort_values
:
df.columns = [i if not i.startswith('Week') else int(i[-1]) for i in df]
res = pd.melt(df, id_vars='Shop', var_name='Week', value_name='Hour')\
.sort_values('Shop').reset_index(drop=True)
print(res)
Shop Week Hour
0 1 1 15
1 1 2 5
2 2 1 25
3 2 2 44
...
16 9 2 81
17 9 1 76
18 10 1 62
19 10 2 46
答案 2 :(得分:1)
我会使用类似这样的东西,尽管所有重命名都有些混乱:
# Rename columns with dict comprehension so it can extend to more than week 1 and week 2
df2 = (df.rename(columns={i: int(i.split()[-1]) for i in df.columns[1:]})
.set_index('Shop')
.stack()
.reset_index()
.rename(columns={'level_1':'Week', 0:'Hour'}))
>>> df2
Shop Week Hour
0 1 1 15
1 1 2 5
2 2 1 25
3 2 2 44
4 3 1 11
5 3 2 55
6 4 1 22
7 4 2 21
8 5 1 0
9 5 2 12
10 6 1 -1
11 6 2 51
12 7 1 15
13 7 2 -10
14 8 1 11
15 8 2 25
16 9 1 76
17 9 2 81
18 10 1 62
19 10 2 46