2016-12-02 47 views
5

目前我已经下一个数据帧:在Python创建非唯一的名单假人成列

import pandas as pd 
df= pd.DataFrame({"ID" : ['1','2','3','4','5'], 
        "col2" : [['a', 'b', 'c'], 
           ['c', 'd', 'e', 'f'], 
           ['f', 'b', 'f'], 
           ['a', 'c', 'b'], 
           ['b', 'a', 'b']]}) 

print(df) 
    ID   col2 
0 1  [a, b, c] 
1 2 [c, d, e, f] 
2 3  [f, b, f] 
3 4  [a, c, b] 
4 5  [b, a, d] 

我想创建一个假人的COL2一个新的数据帧,这样的:

ID a b c d e f 
0 1 1 1 1 0 0 0 
1 2 0 0 1 1 1 1 
2 3 0 1 0 0 0 1 
3 4 1 1 1 0 0 0 
4 5 1 1 0 1 0 0 

df2= df.col2.str.get_dummies(sep = ",") 
pd.concat([data['col1'], df], axis=1) 

ID a b b] c c] d d] e f] [a [b [c [f 
1 0 1 0 0 1 0 0 0 0 1 0 0 0 
2 0 0 0 0 0 1 0 1 1 0 0 1 0 
3 0 1 0 0 0 0 0 0 1 0 0 0 1 
4 0 0 1 1 0 0 0 0 0 1 0 0 0 
5 1 0 0 0 0 0 1 0 0 0 1 0 0 

使用:

使用以下代码中的每个列的列表中的字母的生成不同的列以下代码根据列的位置为列的每个字母生成不同的列。你们有没有人知道你为什么要经历这个? pd.get_dummies选项也不起作用。

回答

3

str.get_dummies适用于字符串,因此您可以将您的列表变成一个分隔字符串并在该字符串上使用str_get_dummies。例如,

df['col2'].str.join('@').str.get_dummies('@') 
Out: 
    a b c d e f 
0 1 1 1 0 0 0 
1 0 0 1 1 1 1 
2 0 1 0 0 0 1 
3 1 1 1 0 0 0 
4 1 1 0 0 0 0 

这里,@是没有出现在列表中的任意字符。

然后,您可以Concat的像往常一样:

pd.concat([df['ID'], df['col2'].str.join('@').str.get_dummies('@')], axis=1) 
Out: 
    ID a b c d e f 
0 1 1 1 1 0 0 0 
1 2 0 0 1 1 1 1 
2 3 0 1 0 0 0 1 
3 4 1 1 1 0 0 0 
4 5 1 1 0 0 0 0 
+0

正如我女儿会说:哇,我的工作!非常感谢你 !!!! –

1

df您所提供...这工作正常

def f1(x): 
    # 1 if exist 
    return pd.Series(1, set(x)) 

def f2(x): 
    # count occurences 
    return pd.value_counts(x) 

print(df.set_index('ID').col2.apply(f1).fillna(0).astype(int).reset_index()) 
print('') 
print(df.set_index('ID').col2.apply(f2).fillna(0).astype(int).reset_index()) 

    ID a b c d e f 
0 1 1 1 1 0 0 0 
1 2 0 0 1 1 1 1 
2 3 0 1 0 0 0 1 
3 4 1 1 1 0 0 0 
4 5 1 1 0 0 0 0 

    ID a b c d e f 
0 1 1 1 1 0 0 0 
1 2 0 0 1 1 1 1 
2 3 0 1 0 0 0 2 
3 4 1 1 1 0 0 0 
4 5 1 2 0 0 0 0 
+0

我喜欢做词数的选项,谢谢! –

+0

你的问题是,为了使用'str'访问器中的'get_dummies',你将它解析为一个导致整个问题的字符串。你左转三圈,右转。这对我来说更直观。然而,'str'是矢量化的,并且会有一些性能优势。总之,很高兴我可以帮助 – piRSquared

3

使用修真类型的字典可能会更快

In [40]: pd.DataFrame({k: 1 for k in x} for x in df.col2.values).fillna(0).astype(int) 
Out[40]: 
    a b c d e f 
0 1 1 1 0 0 0 
1 0 0 1 1 1 1 
2 0 1 0 0 0 1 
3 1 1 1 0 0 0 
4 1 1 0 0 0 0  

In [48]: pd.concat([ 
       df['ID'], 
       pd.DataFrame({k: 1 for k in x} for x in df.col2).fillna(0).astype(int)], 
      axis=1) 
Out[48]: 
    ID a b c d e f 
0 1 1 1 1 0 0 0 
1 2 0 0 1 1 1 1 
2 3 0 1 0 0 0 1 
3 4 1 1 1 0 0 0 
4 5 1 1 0 0 0 0 

计时

In [2942]: df.shape 
Out[2942]: (50000, 2) 

In [2945]: %timeit pd.DataFrame({k: 1 for k in x} for x in df.col2).fillna(0).astype(int) 
10 loops, best of 3: 137 ms per loop 

In [2946]: %timeit df['col2'].str.join('@').str.get_dummies('@') 
1 loop, best of 3: 395 ms per loop 
+0

这太棒了!它速度更快,记忆效率更高! – atonnerre