【问题标题】:Python Pandas: create a new column for each different value of a source column (with boolean output as column values)Python Pandas:为源列的每个不同值创建一个新列(将布尔输出作为列值)
【发布时间】:2018-07-16 17:39:37
【问题描述】:

我正在尝试根据其内容将数据框的源列拆分为几列,然后按以下方式用布尔值 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 填充新列,但这非常无效。

有没有快速有效的方法?

【问题讨论】:

  • 您要查找的关键字是“虚拟变量”。我已提交编辑,将此标签添加到您的问题中。请注意,您可以使用for value in set(df['source_column']): df['value {}'.format(value)] = (df['source_column'] == value).apply(int) 执行此操作,但使用get_dummies 方法更好。

标签: python python-3.x pandas dataframe dummy-variable


【解决方案1】:

你可以试试:

df = pd.get_dummies(df, columns=['source_column'])

或者如果你更喜欢 sklearn

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      所以有这种可能性(有点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
      

      您当然必须重命名列并删除Nancol,但这应该可以满足您的首次运行需求。

      编辑:

      抑制 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 值。因此,两种方法都可以正常工作,您可以选择最能满足您需求的一种。

      【讨论】:

        【解决方案4】:
        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
        

        【讨论】:

          猜你喜欢
          • 2016-07-13
          • 2018-07-27
          • 1970-01-01
          • 2018-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-09
          相关资源
          最近更新 更多