Python-使用字符串列表对字典列表进行哈希

Python-使用字符串列表对字典列表进行哈希,python,pandas,scikit-learn,feature-engineering,Python,Pandas,Scikit Learn,Feature Engineering,我希望能够获取字典(记录)列表,其中一些列具有值列表作为单元格的值。这里有一个例子 [{'fruit': 'apple', 'age': 27}, {'fruit':['apple', 'banana'], 'age': 32}] 如何获取此输入并对其执行功能哈希(在我的数据集中,我有数千列)。目前我使用的是一种热编码,但这似乎消耗了大量的ram(比我的系统上的内存还要多) 我尝试按上述方式获取数据集,但出现错误: x__ = h.transform(data) Traceback (mos

我希望能够获取字典(记录)列表,其中一些列具有值列表作为单元格的值。这里有一个例子

[{'fruit': 'apple', 'age': 27}, {'fruit':['apple', 'banana'], 'age': 32}]
如何获取此输入并对其执行功能哈希(在我的数据集中,我有数千列)。目前我使用的是一种热编码,但这似乎消耗了大量的ram(比我的系统上的内存还要多)

我尝试按上述方式获取数据集,但出现错误:

x__ = h.transform(data)

Traceback (most recent call last):

  File "<ipython-input-14-db4adc5ec623>", line 1, in <module>
    x__ = h.transform(data)

  File "/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py", line 142, in transform
    _hashing.transform(raw_X, self.n_features, self.dtype)

  File "sklearn/feature_extraction/_hashing.pyx", line 52, in sklearn.feature_extraction._hashing.transform (sklearn/feature_extraction/_hashing.c:2103)

TypeError: a float is required

考虑以下方法:

from sklearn.feature_extraction.text import CountVectorizer

lst = [{'fruit': 'apple', 'age': 27}, {'fruit':['apple', 'banana'], 'age': 32}]

df = pd.DataFrame(lst)

vect = CountVectorizer()

X = vect.fit_transform(df.fruit.map(lambda x: ' '.join(x) if isinstance(x, list) else x))

r = pd.DataFrame(X.A, columns=vect.get_feature_names(), index=df.index)

df.join(r)
结果:

In [66]: r
Out[66]:
   apple  banana
0      1       0
1      1       1

In [67]: df.join(r)
Out[67]:
   age            fruit  apple  banana
0   27            apple      1       0
1   32  [apple, banana]      1       1
更新:从Pandas 0.20.1开始,我们可以直接从稀疏矩阵创建SPARSTAFRAME:

In [13]: r = pd.SparseDataFrame(X, columns=vect.get_feature_names(), index=df.index, default_fill_value=0)

In [14]: r
Out[14]:
   apple  banana
0      1       0
1      1       1

In [15]: r.memory_usage()
Out[15]:
Index     80   
apple     16   # 2 * 8 byte (np.int64)
banana     8   # 1 * 8 byte (as there is only one `1` value)
dtype: int64

In [16]: r.dtypes
Out[16]:
apple     int64
banana    int64
dtype: object

您可以将列表转换为元组,元组是可散列的。这确实有效,尽管我似乎内存不足(32GB),但我想有很多列。我还注意到,当我将df分开,以便我可以一组一组地进行时,它给了我很多NaN(即使我提前从数据帧中删除了所有NaN),我意识到我得到na的原因是因为我没有将axis设置为1@Kevin,在Pandas 0.20.1中,您可以直接从稀疏矩阵创建SPARSTAFRAME(CountVectorizer的结果)。请检查我的更新答案。事实上,对于字段中的数字,只需输入一个类型(str)即可。谢谢!@Kevin,很高兴这有帮助:)
In [66]: r
Out[66]:
   apple  banana
0      1       0
1      1       1

In [67]: df.join(r)
Out[67]:
   age            fruit  apple  banana
0   27            apple      1       0
1   32  [apple, banana]      1       1
In [13]: r = pd.SparseDataFrame(X, columns=vect.get_feature_names(), index=df.index, default_fill_value=0)

In [14]: r
Out[14]:
   apple  banana
0      1       0
1      1       1

In [15]: r.memory_usage()
Out[15]:
Index     80   
apple     16   # 2 * 8 byte (np.int64)
banana     8   # 1 * 8 byte (as there is only one `1` value)
dtype: int64

In [16]: r.dtypes
Out[16]:
apple     int64
banana    int64
dtype: object