2017-08-08 262 views
3

我有一个像拆分列表分为

uid         services 
000c80b7d2b3643689b1e516918ec193 ['A'] 
001b292c588ec6cc11f57324d40e422d ['B','A',C'] 
006696f65899fdd87ba4894c784716f9 ['C','B'] 

一个DF(不在服务列排序列表)

我想重新映射在列列表

uid         services  A B C 
000c80b7d2b3643689b1e516918ec193 ['A']   1 0 0 
001b292c588ec6cc11f57324d40e422d ['B','A',C'] 1 1 1 
006696f65899fdd87ba4894c784716f9 ['C','B']  0 1 1 

谢谢

+0

您是否检查了此线程https://stackoverflow.com/questions/37474001/converting-list-in-panda-dataframe-into-columns –

+0

[将熊猫数据框中的列表转换为列](https:// stackoverflow.com/questions/37474001/converting-list-in-panda-dataframe-into-co列) –

回答

0

您可以先使用MultiLabelBinarizer,然后使用join

from sklearn.preprocessing import MultiLabelBinarizer 
mlb = MultiLabelBinarizer() 

print (pd.DataFrame(mlb.fit_transform(df['services']),columns=mlb.classes_, index=df.index)) 
    A B C 
0 1 0 0 
1 1 1 1 
2 0 1 1 

df1 = pd.DataFrame(mlb.fit_transform(df['services']),columns=mlb.classes_, index=df.index) 
df = df.join(df1) 
print (df) 
           uid services A B C 
0 000c80b7d2b3643689b1e516918ec193  [A] 1 0 0 
1 001b292c588ec6cc11f57324d40e422d [B, A, C] 1 1 1 
2 006696f65899fdd87ba4894c784716f9  [C, B] 0 1 1 

纯大熊猫替代与get_dummiesgroupby按列与骨料max

df1 = pd.get_dummies(pd.DataFrame(df['services'].values.tolist()), prefix='', prefix_sep='') 
     .groupby(axis=1, level=0).max() 
print (df1) 
    A B C 
0 1 0 0 
1 1 1 1 
2 0 1 1 

df = df.join(df1) 
print (df) 
           uid services A B C 
0 000c80b7d2b3643689b1e516918ec193  [A] 1 0 0 
1 001b292c588ec6cc11f57324d40e422d [B, A, C] 1 1 1 
2 006696f65899fdd87ba4894c784716f9  [C, B] 0 1 1 

时序

#3k rows 
df = pd.concat([df]*1000).reset_index(drop=True) 

#John Galt solution 
In [255]: %timeit (df.join(df.services.apply(lambda x: pd.Series({y:1 for y in x})).fillna(0).astype(int))) 
1 loop, best of 3: 658 ms per loop 

#user1717828 solution 
In [256]: %timeit (df.join(df['services'].apply(lambda x: "|".join(x)).str.get_dummies())) 
100 loops, best of 3: 16.8 ms per loop 

#Jez solution1 
In [257]: %timeit (df.join(pd.DataFrame(mlb.fit_transform(df['services']),columns=mlb.classes_, index=df.index))) 
100 loops, best of 3: 4.66 ms per loop 

#Jez solution2 
In [258]: %timeit (df.join(pd.get_dummies(pd.DataFrame(df['services'].values.tolist()), prefix='', prefix_sep='').groupby(axis=1, level=0).max())) 
100 loops, best of 3: 7.04 ms per loop 

#30k rows 
df = pd.concat([df]*10000).reset_index(drop=True) 


#John Galt solution 
In [260]: %timeit (df.join(df.services.apply(lambda x: pd.Series({y:1 for y in x})).fillna(0).astype(int))) 
1 loop, best of 3: 6.68 s per loop 

#user1717828 solution 
In [261]: %timeit (df.join(df['services'].apply(lambda x: "|".join(x)).str.get_dummies())) 
10 loops, best of 3: 138 ms per loop 

#Jez solution1 
In [262]: %timeit (df.join(pd.DataFrame(mlb.fit_transform(df['services']),columns=mlb.classes_, index=df.index))) 
10 loops, best of 3: 39.8 ms per loop 

#Jez solution2 
In [263]: %timeit (df.join(pd.get_dummies(pd.DataFrame(df['services'].values.tolist()), prefix='', prefix_sep='').groupby(axis=1, level=0).max())) 
10 loops, best of 3: 20.6 ms per loop 
+0

谢谢!有没有纯粹的熊猫选择? – user3620915

+0

嗯,它似乎更快一点。 – jezrael

+0

@ user3620915,请参阅我对纯熊猫替代品的回答,但是jezrael表明它不如他的速度快。 – user1717828

0
In [1158]: df.join(df.services.apply(lambda x: pd.Series({y:1 for y in x})).fillna(0)) 
Out[1158]: 
           uid services A B C 
0 000c80b7d2b3643689b1e516918ec193  [A] 1.0 0.0 0.0 
1 001b292c588ec6cc11f57324d40e422d [B, A, C] 1.0 1.0 1.0 
2 006696f65899fdd87ba4894c784716f9  [C, B] 0.0 1.0 1.0 
0

DF [ 'A'] =列表(图(拉姆达×:1,如果 'A' 在X否则为0,DF [ '服务'] tolist()))

DF [ 'B'] = list(map(lambda x:1 if'B'in x else 0,df ['Services']。tolist()))

df ['C'] = list(map(lambda x:1 if以x否则为0, 'C' DF [ '服务'] tolist()))

0

快速解答

df.join(df['services'].apply(lambda x: "|".join(x)).str.get_dummies()) 

一种方法是把人物的名单为分隔字符串(使用管道符号|这里),并使用pd.Series.str.get_dummies

df = pd.DataFrame([[['A']],[list('ABC')],[list('BC')]], 
        columns=['services'], 
        index=['abc','def','ghi']) 
df.index.name = 'UID' 
df 

     services 
UID   
abc  [A] 
def [A, B, C] 
ghi  [B, C] 

(df['services'] 
.apply(lambda x: "|".join(x)) 
.str.get_dummies()) 

    A B C 
UID   
abc 1 0 0 
def 1 1 1 
ghi 0 1 1 

合并成原就变成一个班轮:

df.join(df['services'].apply(lambda x: "|".join(x)).str.get_dummies()) 
     services A B C 
UID      
abc  [A] 1 0 0 
def [A, B, C] 1 1 1 
ghi  [B, C] 0 1 1