展开熊猫数据框列

时间:2018-08-08 09:25:39

标签: python string pandas dataframe text

我有一个看起来像这样的Pandas Dataframe:

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)

4 个答案:

答案 0 :(得分:3)

您可以使用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

答案 1 :(得分: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(" ", "")

其余代码相同。

答案 2 :(得分:1)

一个简单的解决方案是按如下方式使用require_once ('/include/SwiftMailer/vendor/autoload.php'); $transport = new Swift_SendmailTransport('localhost', 25); $mailer = new Swift_Mailer($transport); $message = (new Swift_Message('Wonderful Subject')) ->setFrom(['xxxxxxxxx' => 'xxxx']) ->setTo(['xxxxxxxxxx' => 'xxxx']) ->setBody('Here is the message itself') ; // Send the message $result = $mailer->send($message);

pd.get_dummies

答案 3 :(得分:1)

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

scala> val resultList =
           list2.map(x=>list1.filter(y=>y._2.contains(x))).map{
       case List() =>
       case List((a,b)) if(b.size==1) => (a,b,"","")
       case List((a,b)) if(b.size==2) => (a,"",b,"")
       case List((a,b)) if(b.size==3) => (a,"","",b)
       case List((a,b),(_,c)) if(b.size==1 && c.size==2)=>(a,b,c,"")
       case List((a,b),(_,c)) if(b.size==2 && c.size==1)=>(a,c,b,"")
       case List((a,b),(_,c)) if(b.size==1 && c.size==3)=>(a,b,"",c)
       case List((a,b),(_,c)) if(b.size==3 && c.size==1)=>(a,c,"",b)
       case List((a,b),(_,c)) if(b.size==2 && c.size==3)=>(a,"",b,c)
       case List((a,b),(_,c)) if(b.size==3 && c.size==2)=>(a,"",c,b)
       case List((a,b),(_,c),(_,d)) if(b.size==1&&c.size==2 && d.size==3)=> 
            (a,b,c,d)
       case List((a,b),(_,c),(_,d)) if(b.size==1&&c.size==3 && d.size==2)= 
            (a,b,d,c)
       case List((a,b),(_,c),(_,d)) if(b.size==2&&c.size==1&& d.size==3)=>  
            (a,c,b,d)
       case List((a,b),(_,c),(_,d)) if(b.size==2&&c.size==3&& d.size==1)=>  
            (a,d,b,c)
       case List((a,b),(_,c),(_,d)) if(b.size==3&&c.size==1&& d.size==2)=>  
            (a,c,d,b)
       case List((a,b),(_,c),(_,d)) if(b.size==3&&c.size==2&& d.size==1)=>  
            (a,d,c,b)

       }
resultList: List[Any] = List((1,A,AA,AAA), (2,B,BB,""), (3,C,CC,CCC), (4,"",DD,""))

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

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

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

答案

max_label = len(unique)