Python:为源列的每个不同值创建一个新列(将布尔输出作为列值)

Python:为源列的每个不同值创建一个新列(将布尔输出作为列值),python,python-3.x,pandas,dataframe,dummy-variable,Python,Python 3.x,Pandas,Dataframe,Dummy Variable,我正在尝试根据数据帧的内容将其源列拆分为多个列,然后用布尔值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

我正在尝试根据数据帧的内容将其源列拆分为多个列,然后用布尔值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填充新列,但这是非常无效的


有没有一种快速有效的方法可以做到这一点?

所以有这种可能性(有点老套)

从示例数据中读取数据帧:

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

然后与以下人员合作:

当然,您必须重命名列并删除
Nan
col,但这应该可以在第一次运行时满足您的需要

编辑: 另一种抑制nan列的方法是,可以使用groupby+value\u计数(也有点黑):

这是相同的想法(取消堆叠),但会抑制默认情况下要考虑的
nan
值。当然,如果需要的话,您必须将其合并到原始数据帧上,以保留具有nan值的行。总之,这两种方法都很有效,您可以选择最能满足您需求的方法。

您可以尝试:

df = pd.get_dummies(df, columns=['source_column'])
或者如果你喜欢学习

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
matrix=enc.fit_transform(df['source_column'])

您可以使用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

您要查找的关键字是“虚拟变量”。我已提交一份编辑,将此标签添加到您的问题中。注意,您可以使用集合中的值(df['source\u column']):df['value{}.format(value)]=(df['source\u column']==value)的
来实现这一点。应用(int)
,但使用
获取虚拟对象
方法更好。
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
matrix=enc.fit_transform(df['source_column'])
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
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