如何在Pandas中将列转换为行

3
data = [[1, 'tom', 10, 53, 2, 3, 9, 6 ], [2, 'nick', 1, 53, 2, 23, 4, 7], [3, 'juli', 9, 23, 2, 31, 9, 3]]
  
df = pd.DataFrame(data, columns = ['ID', 'Name', 'Apple.Food.0', 'Apple.Food.1', 'Apple.Food.2', 'Pear.Food.0', 'Pear.Food.1', 'Pear.Food.2'])
  
df
ID 姓名 苹果.食物.0 苹果.食物.1 苹果.食物.2 梨.食物.0 梨.食物.1 梨.食物.2
1 汤姆 10 53 2 3 9 6
2 尼克 1 53 2 23 4 7
3 朱莉 9 23 2 31 9 3

我想将最后六列展开为如下格式: 即Apple.Food.0 - 将前缀“Apple”展开到行中,将后缀“0”展开到行中,保留“Food”作为列名并将值保留在那里;然后重新生成ID列作为PK。

我尝试使用.str.split()来分裂列,但是值将与所有被分开的列一起出现。有什么内置的Pandas函数可以轻松实现这一点吗?

ID编号 名称 水果 时间 食物
1 汤姆 苹果 0 10
2 汤姆 苹果 1 53
3 汤姆 苹果 2 2
4 汤姆 梨子 0 3
5 汤姆 梨子 1 9
6 汤姆 梨子 2 6
7 尼克 苹果 0 1
8 尼克 苹果 1 53
9 尼克 苹果 2 2
10 尼克 梨子 0 23
11 尼克 梨子 1 4
12 尼克 梨子 2 7
13 朱莉 苹果 0 9
14 朱莉 苹果 1 23
15 朱莉 苹果 2 2
16 朱莉 梨子 0 31
17 朱莉 梨子 1 9
18 朱莉 梨子 2 3

1
df.melt()然后.str.split()... - Quang Hoang
1个回答

2
使用 DataFrame.set_index 将没有点号的列设置为 MultiIndex,然后使用 str.split 分割列,通过 DataFrame.stack 重塑数据,使用 DataFrame.rename_axis 检查索引名称,最后添加 DataFrame.reset_index
df1 = df.set_index(['ID','Name'])
df1.columns = df1.columns.str.split('.', expand=True)
df1 = df1.stack([0,2]).rename_axis(['ID','Name','Fruit','Time']).reset_index()
print (df1)
    ID  Name  Fruit Time  Food
0    1   tom  Apple    0    10
1    1   tom  Apple    1    53
2    1   tom  Apple    2     2
3    1   tom   Pear    0     3
4    1   tom   Pear    1     9
5    1   tom   Pear    2     6
6    2  nick  Apple    0     1
7    2  nick  Apple    1    53
8    2  nick  Apple    2     2
9    2  nick   Pear    0    23
10   2  nick   Pear    1     4
11   2  nick   Pear    2     7
12   3  juli  Apple    0     9
13   3  juli  Apple    1    23
14   3  juli  Apple    2     2
15   3  juli   Pear    0    31
16   3  juli   Pear    1     9
17   3  juli   Pear    2     3

性能:

#3k rows
df = pd.concat([df] * 1000, ignore_index=True)

def f1():
    df1 = df.set_index(['ID','Name'])
    df1.columns = df1.columns.str.split('.', expand=True)
    df1 = df1.stack([0,2]).rename_axis(['ID','Name','Fruit','Time']).reset_index()
    
def f2():
    x = df.melt(['ID', 'Name'], value_name='Food')
    x[['Fruit', 'Time']] = x.variable.str.split('.', expand=True)[[0,2]]
    x = x.sort_values(['ID', 'Fruit']).reset_index(drop=True).drop('variable', 1)
    

In [41]: %timeit f1()
27.4 ms ± 1.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [42]: %timeit f2()
53.1 ms ± 1.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

谢谢Jezrael,您如何更新ID列以具有唯一键? - Hello World
@VictorZhao - 当然,使用 df['ID'] = range(1, len(df)+1) - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接