我有熊猫数据帧为:
df = pd.DataFrame([[1,0,0,1], [0,1,0,0], [0,0,0,0], [1,0,0,0]], columns=list("ABCD"))
>>> df
A B C D
0 1 0 0 1
1 0 1 0 0
2 0 0 0 0
3 1 0 0 0
我想创建一个与df
高度相同的单列数据帧,带有标签,因为对于一行中 1 和 0 的每个组合,它分配了一个不同的类(最好是数字(,即这个 df 应该看起来像这样:
>>> df_labels
x
0 0
1 1
2 2
3 3
寻找基于熊猫或sklearn等库中已经内置的功能的解决方案,而不是从头开始编码,尽管任何帮助都值得赞赏。
我现在提出了这样的解决方案:
from sklearn.preprocessing import LabelEncoder
labels = []
for i in range(0, len(df)):
# create string from every row
val = "".join([str(x) for x in df.loc[i]])
labels.append(val)
# encode numeric labels for strings created
enc = LabelEncoder()
enc.fit(labels)
df_labels = pd.DataFrame(enc.transform(labels))
>>> df_labels
0
0 3
1 1
2 0
3 2
但是,有没有更好的方法可以做到这一点?
如果您只需要一个通用标签编码(而不是按照您想要的输出顺序(来分隔列"A"、"B"、"C"、"D"的组合,使用dot
是一种简单的方法
n = np.arange(1, len(df.columns)+1)
Out[14]: array([1, 2, 3, 4])
df.dot(n)
Out[15]:
0 5
1 2
2 0
3 1
dtype: int64
因此,每个组合都将编码为dot
提供的唯一值
你可以用factorize
pd.factorize(df.apply(tuple,1))[0]
array([0, 1, 2, 3])
pd.Series(pd.factorize(df.apply(tuple,1))[0])
0 0
1 1
2 2
3 3
dtype: int64
据我所知,没有内置方法,但您可以执行以下操作:
df.apply(lambda x: ('_').join(str(x.values)), axis=1).astype('category').cat.codes