首页 > 解决方案 > 基于 2 列合并和对齐列

问题描述

我有一个如下的df:

ID  P1   P2   P3_1_A  P3_2_B   P4_1_A  P4_2_B
1   110  111   1        0       1       1
2   111  112   0        0       1       0
3   110  112   0        1       0       0
4   112  111   1        1       1       1

因此,P1 和 P2 有 3 个不同的值110和。111112

列 P3 和 P4 的数量总是相等(在上述情况下为 2),但可能因数据而异。

我想要一个结果数据框,其中所有 P3 值与 P1 对齐,所有 P4 值与 P2 对齐,列重命名,如下所示

ID   P     P_A   P_B
1    110    1     0
1    111    1     1
2    111    0     0
2    112    1     0
3    110    0     1
3    112    0     0
4    112    1     1
4    111    1     1

我知道如何合并 P1 和 P2 并到达 P 列,但不知道如何将 P3 和 P4 与 P1 和 P2 对齐并到达 P_1 和 P_2

标签: pythonpandasreshape

解决方案


您可以重命名_子字符串的列,因此可以转换ID为索引并将所有值拆分为MultiIndex最后一次整形DataFrame.stack

df1 = df.rename(columns={'P1':'P3_','P2':'P4_'}).set_index('ID')
df1.columns = df1.columns.str.split('_', expand=True, n=1)
df1 = df1.stack(0).add_prefix('P').reset_index(level=1, drop=True).reset_index()
print (df1)
   ID    P  P1_A  P2_B
0   1  110     1     0
1   1  111     1     1
2   2  111     0     0
3   2  112     1     0
4   3  110     0     1
5   3  112     0     0
6   4  112     1     1
7   4  111     1     1

编辑:对于更通用的解决方案,可以提取不带双精度的列名_并传递给set_index

print (df)
   ID   P1   P2  P3_1_A  P3_2_B  P4_1_A  P4_2_B  A
0   1  110  111       1       0       1       1  9
1   2  111  112       0       0       1       0  7
2   3  110  112       0       1       0       0  8
3   4  112  111       1       1       1       1  7

df1 = df.rename(columns={'P1':'P3__','P2':'P4__'})

cols = df1.columns[df1.columns.str.count('_') != 2]
df1 = df1.set_index(cols.tolist())
df1.columns = df1.columns.str.split('_', expand=True, n=1)
df1 = df1.stack(0).add_prefix('P').reset_index(level=-1, drop=True).reset_index()
print (df1)
   A  ID  P1_A  P2_B   P_
0  9   1     1     0  110
1  9   1     1     1  111
2  7   2     0     0  111
3  7   2     1     0  112
4  8   3     0     1  110
5  8   3     0     0  112
6  7   4     1     1  112
7  7   4     1     1  111

推荐阅读