代码之家  ›  专栏  ›  技术社区  ›  Jack Arnestad

将字符列编码为序号,但保持数字列相同

  •  1
  • Jack Arnestad  · 技术社区  · 6 年前

    test = {"viral": "pos", "Status": "positive", "Age": 59, "score": 5}
    test2 = {"viral": "neg"}
    df = pd.DataFrame.from_dict([test, test2])
    

    我想将字符列(病毒、状态)编码为序数,但不要使用数值。所需的输出是具有相同列名的numpy数组。

    如果我使用sklearn的OrdinalEncoder,它不会处理NaN值。即使没有NaN值,它仍然会对数字列进行顺序编码。我想在字符列中用0填充NaN值,但在数字列中保留NaN。

    所需输出(在numpy数组中):

        Age    Status  score viral
    0  59.0         1    5.0     1
    1   NaN         0    NaN     0
    

    杰克

    编辑:我还想从编码值映射到原始值,如 {i: dict(enumerate(v)) for i, v in enumerate(enc.categories_)} 使用时 enc=OrdinalEncoder() (见 Vectorize 2D character array column-wise

    2 回复  |  直到 6 年前
        1
  •  2
  •   rafaelc    6 年前

    使用 LabelEncoder

    enc = sklearn.preprocessing.LabelEncoder()
    
    mask = df.dtypes.eq(np.object)
    df.loc[:, mask] = df.loc[:, mask].astype(str).apply(enc.fit_transform)
    

    为了你能 inverse_transform defaultdict 属于 LabelEncoders . 这个 key

    from collections import defaultdict
    enc = defaultdict(sklearn.preprocessing.LabelEncoder)
    
    mask = df.dtypes.eq(np.object)
    df.loc[:, mask] = df.loc[:, mask].astype(str).apply(lambda s: enc[s.name].fit_transform(s))
    
        Status  viral
    0   1       1
    1   0       0
    

    df.loc[:, mask].apply(lambda s: enc[s.name].inverse_transform(s))
    
        Status      viral
    0   positive    pos
    1   NaN         neg
    
        2
  •  2
  •   BENY    6 年前

    更新,当有NaN时,它会将代码cat为-1,如果需要NaN,可以使用 replace

    df=pd.DataFrame([test,test2])
    df.dtypes
    Out[152]:
    Age       float64
    Status     object
    score     float64
    viral      object
    dtype: object
    listc=df.columns[df.dtypes=='object']
    
    for x in listc:
        df[x]=df[x].astype('category').cat.codes
    
    df
    Out[156]: 
        Age  Status  score  viral
    0  59.0       0    5.0      1
    1   NaN      -1    NaN      0