我有一个 df 像
uid services
000c80b7d2b3643689b1e516918ec193 ['A']
001b292c588ec6cc11f57324d40e422d ['B','A',C']
006696f65899fdd87ba4894c784716f9 ['C','B']
(服务列中未排序的列表)
我想重新映射列中的列表
uid services A B C
000c80b7d2b3643689b1e516918ec193 ['A'] 1 0 0
001b292c588ec6cc11f57324d40e422d ['B','A',C'] 1 1 1
006696f65899fdd87ba4894c784716f9 ['C','B'] 0 1 1
谢谢
最佳答案
您可以使用 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
纯 Pandas 替代品 get_dummies
和 groupby
按具有聚合 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
关于python - 将列表拆分为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45570632/