Python3如何从一列中指定序号值并基于另一列创建多行

2024-04-27 16:03:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我如何通过在ColA中创建新列(按逗号“,”分割值)并指定其排序值来转换下面的数据集。是否正在为按空格“”拆分的ColB创建多行?同时创建另一列进行索引

当前数据帧

Record_No         COlA           ColB
 1                A1,A2,A3       B1 B2 
 2                A4,A5          B3
 3                A1,A4,A2     

预期结果

NewNo.  Record_No         A1    A2    A3   A4   A5     ColB
  1        1               1     2    3    0    0       B1
  2        1               1     2    3    0    0       B2
  3        2               0     0    0    1    2       B3 
  4        3               1     3    0    2    0       Blank 

Tags: 数据noa2排序a1recordb2a3
2条回答

您必须使用:

  • str.splitCOlAColB中的字符串转换为列表
  • explode将这些列表转换为行
  • get_dummies以生成包含0和1值的指示符列
  • group-by.sum对每个记录的行进行分组\u编号,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 column

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

如果你需要新的号码。列,它现在是微不足道的:

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

这可以通过三个简单的步骤来完成

首先,创建ColB的分解视图

df['ColB'] = df.ColB.str.split(' ')
exp_df = df.explode('ColB')

然后,使用ColA中的项目索引创建列

index_df = (
    exp_df.COlA.apply(lambda x: pd.Series(
        {v:i for i, v in enumerate(x)}
    )
).add(1).fillna(0).astype(int)

然后将两者连接起来

pd.concat([exp_df, index_df], axis=1)

输出

   Record_No          COlA  ColB  A1  A2  A3  A4  A5
0          1  [A1, A2, A3]    B1   1   2   3   0   0
0          1  [A1, A2, A3]    B2   1   2   3   0   0
1          2      [A4, A5]    B3   0   0   0   1   2
2          3  [A1, A4, A2]  None   1   3   0   2   0

注意:如果需要,可以删除COlA

相关问题 更多 >