Pandas - 用用于机器学习的 numpy 数组替换分类文本
Pandas - replace categorical text with numpy arrays for machine learning
我有一个文件:
data = pd.read('data.csv')
并且该文件包含有关数字用户的分类文本数据,例如:(source = 'google', 'facebook', 'twitter') 和 (country = 'US', 'FR', 'GER').
使用 sklearn.feature_extraction.DictVectorizer()
class,我设法将这些类别转换为 numpy 数组。然后我创建了一个字典,其中包含作为键的文本类别,以及作为值的相关类别的矢量化 numpy 数组,即:
{'google': np.array([0., 0., 0., 0., 1.])}
{'facebook': np.array([1., 0., 0., 0., 0.])}
{'FR': np.array([0., 0., 1.])}
理想情况下,我想做的是用它的矢量化 numpy 数组值(例如,np.array([0., 0., 0., 0., 1.]
)替换每个文本类别(例如,'google'),这样我就可以使用一个功能减少算法将特征减少到 2,用于可视化目的。
理想情况下,数据中的一行显示为:
source | country
google | FR
twitter| US
会读作:
source | country
np.array([0., 0., 0., 0., 1.]) | np.array([0., 0., 1.])
np.array([1., 0., 0., 0., 0.]) | np.array([1., 0., 0.])
有人可以推荐解决此问题的最佳方法吗?
所以我找到了 'a' 解决我的问题的方法,也许不是 'the' 的解决方法。我回去为我的键、值对制作了新字典:
创建列表以存储键和值:
keys = []
values = []
向列表添加键和值:
for column in category_columns:
keys.append(data[column].unique().tolist())
for matrix in vectorized_data:
values.append(matrix)
结果(继续我上面的例子):
keys = ['google', 'facebook', 'twitter']
values = [np.array([0., 0., 0., 0., 1.]), np.array([1., 0., 0., 0., 0.]), np.array([0., 1., 0., 0., 0.])]
创建包含键、值的字典列表:
unique_vect = []
for i in range(0, len(keys)):
unique_vect.append(dict(zip(keys[i], values[i])))
然后我使用 pandas' .map()
函数将现有值替换为我从 DictVectorizer
创建的 numpy 数组
data['affiliate_channel'] = data['affiliate_channel'].map(unique_vect[0].get)
我对每一列都重复了这个步骤。
一点点脑力和几个小时的 Google 就能做到这一点,真是太神奇了。如果有人能想到一个 better/quicker/more Pythonic 的方法来做到这一点,我将不胜感激。
也许这是将分类转换为数值表示的更简洁的操作。因为我最近一直在使用 R,所以我不得不稍微复习一下。 This blog post 是一个很好的资源。
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
d = {'source' : pd.Series(['google', 'facebook', 'twitter','twitter'],
index=['1', '2', '3', '4']),
'country' : pd.Series(['GER', 'GER', 'US', 'FR'],
index=['1', '2', '3', '4'])}
df = pd.DataFrame(d)
df_as_dicts=df.T.to_dict().values()
df.T
给出了转置,然后我们应用 to_dict()
来获取 DictVectorizer 想要的字典列表。 values()
方法 returns 只是值,我们不需要索引。
df_as_dicts:
[{'source': 'google', 'country': 'GER'},
{'source': 'twitter', 'country': 'US'},
{'source': 'facebook', 'country': 'GER'},
{'source': 'twitter', 'country': 'FR'}]
那么使用DictVectorizer的转换如下:
vectorizer = DictVectorizer( sparse = False )
d_as_vecs = vectorizer.fit_transform( df_as_dicts )
导致:
array([[ 0., 1., 0., 0., 1., 0.],
[ 0., 0., 1., 0., 0., 1.],
[ 1., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0.]])
如果我们想检查结果,get_feature_names()
允许我们从向量化器中检索该数组的列名。
vectorizer.get_feature_names()
['source=facebook',
'source=google',
'source=twitter',
'country=FR',
'country=GER',
'country=US']
我们可以确认转换为我们提供了 one-hot 编码形式的测试数据的正确表示。
我有一个文件:
data = pd.read('data.csv')
并且该文件包含有关数字用户的分类文本数据,例如:(source = 'google', 'facebook', 'twitter') 和 (country = 'US', 'FR', 'GER').
使用 sklearn.feature_extraction.DictVectorizer()
class,我设法将这些类别转换为 numpy 数组。然后我创建了一个字典,其中包含作为键的文本类别,以及作为值的相关类别的矢量化 numpy 数组,即:
{'google': np.array([0., 0., 0., 0., 1.])}
{'facebook': np.array([1., 0., 0., 0., 0.])}
{'FR': np.array([0., 0., 1.])}
理想情况下,我想做的是用它的矢量化 numpy 数组值(例如,np.array([0., 0., 0., 0., 1.]
)替换每个文本类别(例如,'google'),这样我就可以使用一个功能减少算法将特征减少到 2,用于可视化目的。
理想情况下,数据中的一行显示为:
source | country
google | FR
twitter| US
会读作:
source | country
np.array([0., 0., 0., 0., 1.]) | np.array([0., 0., 1.])
np.array([1., 0., 0., 0., 0.]) | np.array([1., 0., 0.])
有人可以推荐解决此问题的最佳方法吗?
所以我找到了 'a' 解决我的问题的方法,也许不是 'the' 的解决方法。我回去为我的键、值对制作了新字典:
创建列表以存储键和值:
keys = []
values = []
向列表添加键和值:
for column in category_columns:
keys.append(data[column].unique().tolist())
for matrix in vectorized_data:
values.append(matrix)
结果(继续我上面的例子):
keys = ['google', 'facebook', 'twitter']
values = [np.array([0., 0., 0., 0., 1.]), np.array([1., 0., 0., 0., 0.]), np.array([0., 1., 0., 0., 0.])]
创建包含键、值的字典列表:
unique_vect = []
for i in range(0, len(keys)):
unique_vect.append(dict(zip(keys[i], values[i])))
然后我使用 pandas' .map()
函数将现有值替换为我从 DictVectorizer
data['affiliate_channel'] = data['affiliate_channel'].map(unique_vect[0].get)
我对每一列都重复了这个步骤。
一点点脑力和几个小时的 Google 就能做到这一点,真是太神奇了。如果有人能想到一个 better/quicker/more Pythonic 的方法来做到这一点,我将不胜感激。
也许这是将分类转换为数值表示的更简洁的操作。因为我最近一直在使用 R,所以我不得不稍微复习一下。 This blog post 是一个很好的资源。
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
d = {'source' : pd.Series(['google', 'facebook', 'twitter','twitter'],
index=['1', '2', '3', '4']),
'country' : pd.Series(['GER', 'GER', 'US', 'FR'],
index=['1', '2', '3', '4'])}
df = pd.DataFrame(d)
df_as_dicts=df.T.to_dict().values()
df.T
给出了转置,然后我们应用 to_dict()
来获取 DictVectorizer 想要的字典列表。 values()
方法 returns 只是值,我们不需要索引。
df_as_dicts:
[{'source': 'google', 'country': 'GER'},
{'source': 'twitter', 'country': 'US'},
{'source': 'facebook', 'country': 'GER'},
{'source': 'twitter', 'country': 'FR'}]
那么使用DictVectorizer的转换如下:
vectorizer = DictVectorizer( sparse = False )
d_as_vecs = vectorizer.fit_transform( df_as_dicts )
导致:
array([[ 0., 1., 0., 0., 1., 0.],
[ 0., 0., 1., 0., 0., 1.],
[ 1., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0.]])
如果我们想检查结果,get_feature_names()
允许我们从向量化器中检索该数组的列名。
vectorizer.get_feature_names()
['source=facebook',
'source=google',
'source=twitter',
'country=FR',
'country=GER',
'country=US']
我们可以确认转换为我们提供了 one-hot 编码形式的测试数据的正确表示。