你必须使用:
-
str.split 将字符串从 COlA 和 ColB 转换为列表
-
explode 将这些列表转换为行
-
get_dummies 构建包含 0 和 1 值的指标列
-
group-by.sum 按 Record_No,ColB 对对以上行进行分组
困难的部分是您想在 Ai 列中使用排序值而不仅仅是 1。所以我会使用enumerate 来获取该排序值并使用它来乘以get_dummies 将提供的值。
可能的代码:
# explode the "lists" and keep the ordering value for COlA
result = df.assign(COlA=df['COlA'].str.split(',').apply(
lambda x: list(enumerate(x, 1)))).assign(ColB=df['ColB'].str.split(' ')
).explode('COlA').explode('ColB')
# separate the ordering value from the value itself in different columns
result['Coeff'] = result['COlA'].apply(lambda x: x[0])
result['COlA'] = result['COlA'].apply(lambda x: x[1])
它给出:
Record_No COlA ColB Coeff
0 1 A1 B1 1
0 1 A1 B2 1
0 1 A2 B1 2
0 1 A2 B2 2
0 1 A3 B1 3
0 1 A3 B2 3
1 2 A4 B3 1
1 2 A5 B3 2
2 3 A1 None 1
2 3 A4 None 2
2 3 A2 None 3
让我们继续:
# build the indicator values and replace None with Blank in ColB
result = pd.get_dummies(result.fillna('Blank'), columns=['COlA'])
# multiply the indicator value by the ordering value
result.iloc[:, 3:] = np.transpose(np.transpose(result.iloc[:, 3:].values
) * result.Coeff.values)
我们有:
Record_No ColB Coeff COlA_A1 COlA_A2 COlA_A3 COlA_A4 COlA_A5
0 1 B1 1 1 0 0 0 0
0 1 B2 1 1 0 0 0 0
0 1 B1 2 0 2 0 0 0
0 1 B2 2 0 2 0 0 0
0 1 B1 3 0 0 3 0 0
0 1 B2 3 0 0 3 0 0
1 2 B3 1 0 0 0 1 0
1 2 B3 2 0 0 0 0 2
2 3 Blank 1 1 0 0 0 0
2 3 Blank 2 0 0 0 2 0
2 3 Blank 3 0 3 0 0 0
只需重命名列、分组值并删除现在无用的 Coeff 列
result = result.drop(columns='Coeff').rename(
columns=lambda x: x.replace('COlA_', '')).groupby(
['Record_No', 'ColB']).sum().reset_index()
我们得到期望值:
Record_No ColB A1 A2 A3 A4 A5
0 1 B1 1 2 3 0 0
1 1 B2 1 2 3 0 0
2 2 B3 0 0 0 1 2
3 3 Blank 1 3 0 2 0
如果您需要 NewNo.列,它现在是微不足道的:
result = result.rename_axis('NewNo.').reset_index()
我们终于有了:
NewNo. Record_No ColB A1 A2 A3 A4 A5
0 0 1 B1 1 2 3 0 0
1 1 1 B2 1 2 3 0 0
2 2 2 B3 0 0 0 1 2
3 3 3 Blank 1 3 0 2 0