如何对整个列而不是每一列进行一次热编码熊猫数据帧?

时间:2019-05-16 15:27:29

标签: pandas one-hot-encoding

我想对整个列而不是每一列都对熊猫数据框进行一次热编码。

如果存在如下数据框:

df = pd.DataFrame({'A': ['A1', 'A1', 'A1', 'A1', 'A4', 'A5'], 'B': ['A2', 'A2', 'A2', 'A3', np.nan, 'A6], 'C': ['A4', 'A3', 'A3', 'A5', np.nan, np.nan]})
df =
        A    B   C
    0  A1   A2  A4
    1  A1   A2  A3
    2  A1   A2  A3
    3  A1   A3  A5
    4  A4   NaN NaN
    5  A5   A6  NaN

我想像下面这样编码:

    df =
            A1    A2   A3   A4   A5   A6
        0    1     1    0    1    0    0
        1    1     1    1    0    0    0
        2    1     1    1    0    0    0
        3    1     0    1    0    1    0
        4    0     0    0    1    0    0
        5    0     0    0    0    1    1

但是,如果我编写如下代码,则结果如下:

df = pd.get_dummies(df, sparse=True)
df = 
   A_A1  A_A4  A_A5  B_A2  B_A3  B_A6  C_A3  C_A4  C_A5
0     1     0     0     1     0     0     0     1     0
1     1     0     0     1     0     0     1     0     0
2     1     0     0     1     0     0     1     0     0
3     1     0     0     0     1     0     0     0     1
4     0     1     0     0     0     0     0     0     0
5     0     0     1     0     0     1     0     0     0

如何对整个列进行一次热编码? 如果我使用prefix ='',它还会创建诸如_A1 _A4 _A5 _A2 _A3 _A6 _A3 _A4 _A5之类的列。 (我希望使用pandas或numpy库制作代码,而不要使用for-loop天真代码,因为我的数据是如此之大; 1600万行,因此迭代的for-loop天真代码将需要较长的计算时间。)

2 个答案:

答案 0 :(得分:4)

以您的情况

df.stack().str.get_dummies().sum(level=0)
Out[116]: 
   A1  A2  A3  A4  A5  A6
0   1   1   0   1   0   0
1   1   1   1   0   0   0
2   1   1   1   0   0   0
3   1   0   1   0   1   0
4   0   0   0   1   0   0
5   0   0   0   0   1   1

或用pd.get_dummies修复prefix

pd.get_dummies(df, prefix='',prefix_sep='').sum(level=0,axis=1)
Out[118]: 
   A1  A4  A5  A2  A3  A6
0   1   1   0   1   0   0
1   1   0   0   1   1   0
2   1   0   0   1   1   0
3   1   0   1   0   1   0
4   0   1   0   0   0   0
5   0   0   1   0   0   1

答案 1 :(得分:3)

更快

            ID  YEAR ELEMENT  VALUE1  DMFLAG1  QCFLAG1  DSFLAG1
0  10160355000  1878    TAVG     959      NaN      NaN      1.0
1  10160355000  1879    TAVG    1249      NaN      NaN      1.0
2  10160355000  1880    TAVG    1029      NaN      NaN      1.0
3  10160355000  1931    TAVG   -9999      NaN      NaN      NaN
4  10160355000  1932    TAVG    1079      NaN      NaN      1.0

不快

这旨在表明您可以加入行值,然后使用# Pandas 0.24 or greater use `.to_numpy()` instead of `.values` v = df.values n, m = v.shape j, cols = pd.factorize(v.ravel()) # -1 when `np.nan` # Used to grab only non-null values mask = j >= 0 i = np.arange(n).repeat(m)[mask] j = j[mask] out = np.zeros((n, len(cols)), dtype=int) # Useful when not one-hot. Otherwise use `out[i, j] = 1` np.add.at(out, (i, j), 1) pd.DataFrame(out, df.index, cols) A1 A2 A4 A3 A5 A6 0 1 1 1 0 0 0 1 1 1 0 1 0 0 2 1 1 0 1 0 0 3 1 0 0 1 1 0 4 0 0 1 0 0 0 5 0 0 0 0 1 1

str.get_dummies

df.stack().groupby(level=0).apply('|'.join).str.get_dummies() A1 A2 A3 A4 A5 A6 0 1 1 0 1 0 0 1 1 1 1 0 0 0 2 1 1 1 0 0 0 3 1 0 1 0 1 0 4 0 0 0 1 0 0 5 0 0 0 0 1 1

sklearn