我的数据集看起来像这样:
import pandas as pd
pd.DataFrame({"A": [2, 2, 1, 0, 5, 3, 0, 4, 5], "B": [1, 0, 0, 0, 1, 1, 1, 0, 0]})
A B
0 2 1
1 2 0
2 1 0
3 0 0
4 5 1
5 3 1
6 0 1
7 4 0
(我知道A在0到5之间; B只有0或1)
我想改造它并得到:
A0_B0 A1_B0 A2_B0 A3_B0 ... A5_B1
0 0 0 0 0 ...
1 0 0 1 0 ...
2 0 1 0 0 ...
...
(知道哪个列对应哪个组合很重要)
使用可与sklearn Pipeline和/或sklearn_pandas DataFrameMapper集成的方法(需要在测试样本上可重现)。
目前,我已尝试使用OneHotEncoder或LabelBinarizer,但它们适用于A或B列而不混合它们。
我也尝试使用自定义转换器手动操作,但DataFrameMapper会丢失列名:
from sklearn.base import BaseEstimator, TransformerMixin
class ABTransformer(BaseEstimator, TransformerMixin):
def fit(self, x, y=None):
return self
def transform(self, x):
A = x.A
B = x.B
A0_B0 = np.logical_and((A==0), (B == 0))
A1_B0 = np.logical_and((A==1), (B == 0))
...
data = pd.DataFrame(np.stack((A0_B0, A1_B0,.... ), axis=1),
columns=["A0_B0", "A1_B0", ...]
)
return data
mapper = DataFrameMapper([
(["A", "B"], [ABTransformer()] , {'input_df':True, "alias": None}),
],
df_out=True, sparse=False)
最后,我得到的数据标有:" A_B_0"," A_B_1"等...
有没有办法实现所需的输出?
答案 0 :(得分:1)
鉴于A列和B列的不同值的数量分别为n_A
和n_B
,并且所有值都表示为从零开始的整数,您可以使用以下转换函数。
def transform(self, x):
indices = x.B * n_A + x.A
columns = ["A%d_B%d" % (j, i) for i in range(n_B) for j in range(n_A)]
onehot = np.eye(n_A * n_B)[indices]
data = pd.DataFrame(data=onehot, columns=columns)
return data