我试图根据内容在几列中拆分数据框的源列,然后按照以下方式用布尔值1或0填充这些新生成的列:
原始数据框:
ID source_column
A value 1
B NaN
C value 2
D value 3
E value 2
生成以下输出:
ID source_column value 1 value 2 value 3
A value 1 1 0 0
B NaN 0 0 0
C value 2 0 1 0
D value 3 0 0 1
E value 2 0 1 0
我考虑手动创建每个不同的列,然后使用每个列的函数和.apply,用1或0填充新列,但这非常无效。
有一种快速有效的方法吗?
答案 0 :(得分:3)
您可以尝试:
df = pd.get_dummies(df, columns=['source_column'])
或者如果你喜欢sklearn
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
matrix=enc.fit_transform(df['source_column'])
答案 1 :(得分:3)
您可以使用pandas函数get_dummies,并将结果添加到df,如下所示
In [1]: col_names = df['source_column'].dropna().unique().tolist()
In [2]: df[col_names] = pd.get_dummies(df['source_column'])
In [3]: df
Out[3]:
ID source_column value 1 value 2 value 3
0 A value 1 1 0 0
1 B NaN 0 0 0
2 C value 2 0 1 0
3 D value 3 0 0 1
4 E value 2 0 1 0
答案 2 :(得分:1)
所以有这种可能性(有点hacky)。
从示例数据中读取DataFrame:
In [4]: df = pd.read_clipboard().drop("ID", axis=1)
In [5]: df
Out[5]:
source_column
A 1.0
B NaN
C 2.0
D 3.0
E 2.0
之后,添加一个包含df['foo'] = 1
的新列。
然后使用unstacking:
In [22]: df.reset_index().set_index(['index', 'source_column']).unstack().fillna(0).rename_axis([None]).astype(int)
Out[22]:
foo
source_column NaN 1.0 2.0 3.0
A 0 1 0 0
B 1 0 0 0
C 0 0 1 0
D 0 0 0 1
E 0 0 1 0
当然,您必须重命名列并删除Nan
col,但这应该会在第一次运行时满足您的需求。
其他抑制nan列的方法,你可以使用groupby + value_counts(也就是hacky):
In [30]: df.reset_index().groupby("index").source_column.value_counts().unstack().fillna(0).astype(int).rename_axis([None])
Out[30]:
source_column 1.0 2.0 3.0
A 1 0 0
C 0 1 0
D 0 0 1
E 0 1 0
这是相同的想法(取消堆叠)但是禁止默认考虑nan
值。您当然必须将其合并到原始数据框上,以便在需要时保留具有nan值的行。所以,两种方法都可以正常工作,您可以选择最能满足您需求的方法。
答案 3 :(得分:1)
pd.concat([df,pd.crosstab(df.index,df.source_column)],1).fillna(0)
Out[1028]:
ID source_column value1 value2 value3
0 A value1 1.0 0.0 0.0
1 B 0 0.0 0.0 0.0
2 C value2 0.0 1.0 0.0
3 D value3 0.0 0.0 1.0
4 E value2 0.0 1.0 0.0