假设我有一个数据框,其中的一列是一个列表(值和长度未知),例如:
df = pd.DataFrame(
{'messageLabels': [['Good', 'Other', 'Bad'],['Bad','Terrible']]}
)
我遇到了这个解决方案,但这不是我想要的。 How best to extract a Pandas column containing lists or tuples into multiple columns
理论上,最终的df看起来像
messageLabels | Good| Other| Bad| Terrible
--------------------------------------------------------
['Good', 'Other', 'Bad'] | True| True |True| False
--------------------------------------------------------
['Bad','Terrible'] |False|False |True| True
见上文
答案 0 :(得分:5)
df.join(df.messageLabels.str.join('|').str.get_dummies().astype(bool))
messageLabels Bad Good Other Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] True False False True
sklearn
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
dum = mlb.fit_transform(df.messageLabels)
df.join(pd.DataFrame(dum.astype(bool), df.index, mlb.classes_))
messageLabels Bad Good Other Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] True False False True
n = len(df)
i = np.arange(n)
l = [*map(len, df.messageLabels)]
j, u = pd.factorize(np.concatenate(df.messageLabels))
o = np.zeros((n, len(u)), bool)
o[i.repeat(l), j] = True
df.join(pd.DataFrame(o, df.index, u))
messageLabels Good Other Bad Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] False False True True
并通过Andy
激发灵感df.join(pd.DataFrame([dict.fromkeys(x, True) for x in df.messageLabels]).fillna(False))
messageLabels Bad Good Other Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] True False False True
答案 1 :(得分:3)
另一种方法是使用apply和Series构造函数:
In [11]: pd.get_dummies(df.messageLabels.apply(lambda x: pd.Series(1, x)) == 1)
Out[11]:
Good Other Bad Terrible
0 True True True False
1 False False True True
其中
In [12]: df.messageLabels.apply(lambda x: pd.Series(1, x))
Out[12]:
Good Other Bad Terrible
0 1.0 1.0 1.0 NaN
1 NaN NaN 1.0 1.0
要获得所需的输出,请执行以下操作:
In [21]: res = pd.get_dummies(df.messageLabels.apply(lambda x: pd.Series(1, x)) == 1)
In [22]: df[res.columns] = res
In [23]: df
Out[23]:
messageLabels Good Other Bad Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] False False True True
答案 2 :(得分:2)
我将使用get_dummies
和sum
(或max
,它们中的任何一个都可以)执行此操作:
tmp = pd.DataFrame(df['messageLabels'].tolist())
pd.get_dummies(tmp, prefix='', prefix_sep='').max(level=0, axis=1).astype(bool)
Bad Good Other Terrible
0 True True True False
1 True False False True
您可以使用df
将其与join
结合使用:
df.join(pd.get_dummies(tmp, prefix='', prefix_sep='')
.max(level=0, axis=1)
.astype(bool))
messageLabels Bad Good Other Terrible
0 [Good, Other, Bad] True True True False
1 [Bad, Terrible] True False False True
您也可以stack
和pivot_table
:
(pd.DataFrame(df['messageLabels'].tolist())
.stack()
.reset_index()
.pivot_table(index='level_0', columns=0, aggfunc='size', fill_value=0)
.astype(bool))
0 Bad Good Other Terrible
level_0
0 True True True False
1 True False False True