Python Pandas - 重塑数据框架

10

给定以下数据框:

pd.DataFrame({"A":[1,2,3],"B":[4,5,6],"C":[6,7,8]})

   A   B   C
0  1   4   6
1  2   5   7
2  3   6   8
3  11  14  16
4  12  15  17
5  13  16  18

我希望能够重新塑造它,使其看起来像这样:

   A   B   C   A_1   B_1   C_1   A_2   B_2   C_2
0  1   4   6     2     5     7     3     6     8
1  11  14  16    12    15    17    13    16    18

因此,每3行被分组为1行

我如何使用Pandas实现这一点?

5个回答

12

一个想法是使用整数和模除创建MultiIndex,并通过DataFrame.unstack进行重塑:

a = np.arange(len(df))
df.index = [a // 3, a % 3]
df = df.unstack().sort_index(axis=1, level=1)
df.columns = [f'{a}_{b}' for a, b in df.columns]
print (df)
   A_0  B_0  C_0  A_1  B_1  C_1  A_2  B_2  C_2
0    1    4    6    2    5    7    3    6    8
1   11   14   16   12   15   17   13   16   18

要进行反向操作,可以使用str.splitDataFrame.stack:

a = np.arange(len(df))
df1 = (df.set_index(pd.MultiIndex.from_arrays([a // 3, a % 3]))
         .unstack().sort_index(axis=1, level=1))
df1.columns = [f'{a}_{b}' for a, b in df1.columns]
print (df1)
   A_0  B_0  C_0  A_1  B_1  C_1  A_2  B_2  C_2
0    1    4    6    2    5    7    3    6    8
1   11   14   16   12   15   17   13   16   18

df1.columns = df1.columns.str.split('_', expand=True)
df2 = df1.stack().reset_index(drop=True)
print (df2)
    A   B   C
0   1   4   6
1   2   5   7
2   3   6   8
3  11  14  16
4  12  15  17
5  13  16  18

谢谢您的回答,您如何撤销此操作? - Shlomi Schwartz

10
new = pd.concat([df[a::3].reset_index(drop=True) for a in range(3)], axis=1)
new.columns = ['{}_{}'.format(a,b) for b in range(3) for a in 'ABC']

3
你可以尝试这个:
pd.DataFrame(
    data=df.values.reshape([-1, df.values.shape[1]*3]),
    columns=list(df.columns) + sum([[c+'_'+str(i) for c in df.columns] for i in range(1, 3)], [])
)

你的输入数据框的输出结果:


    A   B   C   A_1 B_1 C_1 A_2 B_2 C_2
0   1   4   6   2   5   7   3   6   8
1   11  14  16  12  15  17  13  16  18

3

每三行数据进行一次转换:我们可以使用numpy的reshape方法对数据进行转换,并创建一个range(1,3)和列的笛卡尔积来获取新列:

from itertools import product
row = len(df)//3

#create new columns
new_columns = df.columns.union(["_".join((letter,str(num))) 
                                for letter,num in product(df.columns,range(1,3))],
                               sort=False)

#create new dataframe
new_df = pd.DataFrame(np.reshape(df.to_numpy(),(row,-1)), 
                      columns=new_columns)
new_df

    A   B   C   A_1 A_2 B_1 B_2 C_1 C_2
0   1   4   6   2   5   7   3   6   8
1   11  14  16  12  15  17  13  16  18

2
我们可以按照重复的一组n(在这种情况下为3)来分组您的数据,然后使用pd.concat将它们沿着列轴连接起来:
n = 3
grps = df.groupby(df.index // n).cumcount()
dfn = pd.concat([d.reset_index(drop=True) for _, d in df.groupby(grps)], axis=1)
dfn.columns = [f'{col}_{i}' for col, i in zip(dfn.columns, np.arange(dfn.shape[1]) // n)]

   A_0  B_0  C_0  A_1  B_1  C_1  A_2  B_2  C_2
0    1    4    6    2    5    7    3    6    8
1   11   14   16   12   15   17   13   16   18

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