【问题标题】:exploding a pandas dataframe column爆炸熊猫数据框列
【发布时间】:2019-01-15 12:09:37
【问题描述】:

我有一个看起来像这样的 Pandas 数据框:

text = ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz"]

labels = ["label_1, label_2", 
          "label_1, label_3, label_2", 
          "label_2, label_4", 
          "label_1, label_2, label_5", 
          "label_2, label_3", 
          "label_3, label_5, label_1, label_2", 
          "label_1, label_3"]

df = pd.DataFrame(dict(text=text, labels=labels))
df



   text                              labels
0  abcd                    label_1, label_2
1  efgh           label_1, label_3, label_2
2  ijkl                    label_2, label_4
3  mnop           label_1, label_2, label_5
4  qrst                    label_2, label_3
5  uvwx  label_3, label_5, label_1, label_2
6    yz                    label_1, label_3

我想把数据框格式化成这样:

text  label_1  label_2  label_3  label_4  label_5

abcd        1.0      1.0      0.0      0.0      0.0
efgh        1.0      1.0      1.0      0.0      0.0
ijkl        0.0      1.0      0.0      1.0      0.0
mnop        1.0      1.0      0.0      0.0      1.0
qrst        0.0      1.0      1.0      0.0      0.0
uvwx        1.0      1.0      1.0      0.0      1.0
yz          1.0      0.0      1.0      0.0      0.0

我怎样才能做到这一点? (我知道我可以拆分标签中的字符串并将它们转换为列表,方法是执行df.labels.str.split(",") 之类的操作,但不确定如何从那里继续。

(所以基本上我想将标签列中的这些关键字转换为自己的列,并在它们出现在预期输出中时填写 1)

【问题讨论】:

标签: python string pandas dataframe text


【解决方案1】:

如果列数是动态的,这将有助于找到可能的列。

unique = df['labels'].apply(lambda x: x.split(", ")).values.tolist()
unique = [i for sublist in unique for i in sublist]
unique = set(unique)

因此,现在是独一无二的。
{'label_1'、'label_2'、'label_3'、'label_4'、'label_5'}

max_label = len(unique)

这将为我们提供最大的列数。

回答

def labeller(labels):
    value = [0] * max_label
    for label in labels:
        value[int(label[-1])-1] = 1
    return value

df['labels'] = df['labels'].apply(lambda x: x.split(", ")).apply(labeller)

df[['label_' + str(i+1) for i in range(max_label)]] = df.labels.apply(pd.Series)
df.drop(['labels'], axis=1, inplace=True)

    text    label_1 label_2 label_3 label_4 label_5
0   abcd    1       1       0       0       0
1   efgh    1       1       1       0       0
2   ijkl    0       1       0       1       0
3   mnop    1       1       0       0       1
4   qrst    0       1       1       0       0
5   uvwx    1       1       1       0       1
6   yz      1       0       1       0       0

【讨论】:

    【解决方案2】:

    代码:

    text = ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz"]
    
    labels = ["label_1, label_2",
              "label_1, label_3, label_2",
              "label_2, label_4",
              "label_1, label_2, label_5",
              "label_2, label_3",
              "label_3, label_5, label_1, label_2",
              "label_1, label_3"]
    
    df = pd.DataFrame(dict(text=text, labels=labels))
    df = df.drop('labels', axis=1).join(
                 df.labels
                 .str
                 .split(', ', expand=True)
                 .stack()
                 .reset_index(drop=True, level=1)
                 .rename('labels')
                 )
    
    df['value'] = 1
    df_new = df.pivot(values = 'value', index='text', columns = 'labels').fillna(0)
    print(df_new)
    

    输出:

    labels  text  label_1  label_2  label_3  label_4  label_5
    0       abcd      1.0      1.0      0.0      0.0      0.0
    1       efgh      1.0      1.0      1.0      0.0      0.0
    2       ijkl      0.0      1.0      0.0      1.0      0.0
    3       mnop      1.0      1.0      0.0      0.0      1.0
    4       qrst      0.0      1.0      1.0      0.0      0.0
    5       uvwx      1.0      1.0      1.0      0.0      1.0
    6         yz      1.0      0.0      1.0      0.0      0.0
    

    在这个主要的事情是拆分使用 (,) 与空间,因为你的字符串格式,如果你改变该格式而不是使用适当的拆分。

    例如:

    如果您像这样使用带有单个逗号的拆分

    df = df.drop('labels', axis=1).join(
                     df.labels
                     .str
                     .split(',', expand=True)
                     .stack()
                     .reset_index(drop=True, level=1)
                     .rename('labels')
                     )
    

    那么您将需要额外的代码来删除空格

    df['labels'] = df['labels'].str.replace(" ", "")
    

    其余代码将相同。

    【讨论】:

      【解决方案3】:

      一个简单的解决方案是使用pd.get_dummies,如下所示:

      pd.get_dummies(
          df.set_index('text')['labels'].str.split(', ', expand=True).stack()
      ).groupby('text').sum()
      

      【讨论】:

        【解决方案4】:

        您可以使用pd.Series.str.get_dummies 并与text 系列结合使用:

        dummies = df['labels'].str.replace(' ', '').str.get_dummies(',')
        res = df['text'].to_frame().join(dummies)
        
        print(res)
        
           text  label_1  label_2  label_3  label_4  label_5
        0  abcd        1        1        0        0        0
        1  efgh        1        1        1        0        0
        2  ijkl        0        1        0        1        0
        3  mnop        1        1        0        0        1
        4  qrst        0        1        1        0        0
        5  uvwx        1        1        1        0        1
        6    yz        1        0        1        0        0
        

        【讨论】:

          猜你喜欢
          • 2022-01-27
          • 2021-05-27
          • 2023-01-19
          • 2018-08-03
          • 1970-01-01
          • 2018-06-20
          • 2012-12-21
          • 2019-12-20
          相关资源
          最近更新 更多