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

时间:2018-02-06 15:41:51

标签: 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              0          0          0
C    value 2          0          1          0
D    value 3          0          0          1
E    value 2          0          1          0

我考虑手动创建每个不同的列,然后使用每个列的函数和.apply,用1或0填充新列,但这非常无效。

有一种快速有效的方法吗?

4 个答案:

答案 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