我有一个数据帧:
data = pd.DataFrame({
'foo': ['hi', 'no', 'please', 'no', 'yea', 'hi'],
'bar': [1, 5, 7, 2, 4, 5],
'zoo': ['car', 'bike', 'car', 'bus', 'bus', 'car']
})
我创建了以列名为键,列/行值为值的字典
X = data.iloc[:]
X_dicts = X.T.to_dict().values()
它产生:
{'foo': 'hi', 'bar': 1, 'zoo': 'car'}
{'foo': 'no', 'bar': 5, 'zoo': 'bike'}
{'foo': 'please', 'bar': 7, 'zoo': 'car'}
{'foo': 'no', 'bar': 2, 'zoo': 'bus'}
{'foo': 'yea', 'bar': 4, 'zoo': 'bus'}
{'foo': 'hi', 'bar': 5, 'zoo': 'car'}
现在我想将每个字典转换为numpy
数组,以便我可以将数组放入scikit-learn
分类器中,所以我这样做了:
vec = feature_extraction.DictVectorizer()
X_vec = vec.fit_transform(X).toarray()
其中产生了:
[[ 1. 1. 0. 0. 0. 0. 0. 1.]
[ 5. 0. 1. 0. 0. 1. 0. 0.]
[ 7. 0. 0. 1. 0. 0. 0. 1.]
[ 2. 0. 1. 0. 0. 0. 1. 0.]
[ 4. 0. 0. 0. 1. 0. 1. 0.]
[ 5. 1. 0. 0. 0. 0. 0. 1.]]
目前为止,一切都好。但是,当我尝试使用其.inverse_transform
方法反转矢量化器时,我没有得到我期望的(这是我的原始字典列表)。我明白这个:
[{'foo=hi': 1.0, 'bar': 1.0, 'zoo=car': 1.0},
{'foo=no': 1.0, 'bar': 5.0, 'zoo=bike': 1.0},
{'foo=please': 1.0, 'bar': 7.0, 'zoo=car': 1.0},
{'foo=no': 1.0, 'bar': 2.0, 'zoo=bus': 1.0},
{'foo=yea': 1.0, 'bar': 4.0, 'zoo=bus': 1.0},
{'foo=hi': 1.0, 'bar': 5.0, 'zoo=car': 1.0}]
那么有人可以告诉我如何取回我的原始词典列表吗?(这些 --> X_dicts = X.T.to_dict().values()
)。您能否解释一下为什么尝试使用带有 DictVectorizer 的 .inverse_transform
方法获取转换前数据并不像对 PCA 使用相同的方法那么容易?
根据文档,
当特征值为字符串时,此转换器将执行二进制独热 (又名 one-of-K)编码:为每个特征构建一个布尔值特征 功能可以采用的可能字符串值。例如,一个 可以取值"火腿"和"垃圾邮件"的特征"F"将变为两个 输出中的特征,一个表示"f=ham",另一个表示"f=垃圾邮件"。
因此,您看到的行为完全符合预期。
若要恢复原始数据帧,可以循环访问feature_map
由 vec.inverse_transform
返回并反转 one-of-K 编码,因此例如,{'foo=bar': 1.0}
变得{'foo':'bar'}
:
import pandas as pd
import sklearn.feature_extraction as FE
data = pd.DataFrame({
'foo': ['hi', 'no', 'please', 'no', 'yea', 'hi'],
'bar': [1, 5, 7, 2, 4, 5],
'zoo': ['car', 'bike', 'car', 'bus', 'bus', 'car']})
X_dicts = data.to_dict('records')
vec = FE.DictVectorizer(sparse=False)
X_vec = vec.fit_transform(X_dicts)
def inverse_transform(vec, X_vec):
feature_map = vec.inverse_transform(X_vec)
result = list()
for dct in feature_map:
newdct = dict()
for k, v in dct.items():
if '=' in k:
k, v = k.split('=', 1)
newdct[k] = v
result.append(newdct)
return result
data2 = pd.DataFrame(inverse_transform(vec, X_vec))
print(data2)
收益 率
bar foo zoo
0 1 hi car
1 5 no bike
2 7 please car
3 2 no bus
4 4 yea bus
5 5 hi car