Python 文本处理和pd.get_dummies()编码会消耗大量RAM
我有一个由标记化和词干化单词组成的数据集,我正在使用Python 文本处理和pd.get_dummies()编码会消耗大量RAM,python,pandas,text,encoding,Python,Pandas,Text,Encoding,我有一个由标记化和词干化单词组成的数据集,我正在使用pd.get_dummies()对它们进行编码。问题是我的数据集相当大,有2054735个单词,其中只有257个是唯一的。问题是,当我开始应用pd.get_dummies()时,我不能使用超过257个字,否则我的内核会崩溃,因为它的内存不足>13Gb。我已经检查了结果数据帧的内存使用情况,7055x257的内存使用量仅为1.8MB 这是我的代码: import pandas as pd df_balanced_features = pd.Se
pd.get_dummies()
对它们进行编码。问题是我的数据集相当大,有2054735个单词,其中只有257个是唯一的。问题是,当我开始应用pd.get_dummies()
时,我不能使用超过257个字,否则我的内核会崩溃,因为它的内存不足>13Gb。我已经检查了结果数据帧的内存使用情况,7055x257的内存使用量仅为1.8MB
这是我的代码:
import pandas as pd
df_balanced_features = pd.Series([["one", "home", "dark"], ["hello", "gamma", "hello"], ["five", "tango", "bravo"]])
df_balanced_features = pd.get_dummies(df_balanced_features.apply(pd.Series).stack()).sum(level = 0)
你知道我如何使用
pd.get_dummies
对250多列进行编码吗?可以手动获取假人,但需要执行以下步骤此过程在创建虚拟列时需要迭代的少量内存产品
import pandas as pd
import numpy as np
df_balanced_features = pd.Series([["one", "home", "dark", "bravo"], ["hello", "gamma", "hello"], ["five", "tango", "bravo"]])
获取唯一的字符串
unique_values = []
for values in df_balanced_features:
for value in values:
if value not in unique_values:
unique_values.append(value)
计算序列中每个列表中每个字符串的频率(类似于级别=0)
转换总行数
total_rows = np.array(total_rows)
total_rows = total_rows.transpose()
创建类似于假人的数据帧
df = pd.DataFrame(total_rows, columns = unique_values)
df
我一直使用gensim软件包来完成这些任务,而且我从未遇到过内存不足的问题。至少在这一步中。NLP可能会占用大量内存
import gensim
from gensim import corpora
dictionary = corpora.Dictionary(df_balanced_features.tolist())
dummy_encoded = df_balanced_features.apply(lambda doc: pd.Series(dict(dictionary.doc2bow(doc)))).fillna(0).astype(int)
dictionary.id2token[0] # id2token is lazy so you need to call it once to create it in memory
dummy_encoded.rename(columns=dictionary.id2token, inplace=True)
这是一种使用内置集合
包中的计数器的方法,它可能比您提供的解决方案占用更少的内存。我使用了dtype=“Int8”
,这是一种支持空(NaN)值的8位整数类型
你能用一个较小的数据集来完成这个任务吗?如果是这样,您能否运行它并监视内存使用情况,以查看它在完成运行后是否会下降?我很好奇是最终的数据帧占用了太多的内存还是中间步骤之一。最终的数据帧非常小,大约有300个唯一的字,大小约为2MB。很明显,这种过度的RAM使用发生在中间的一个步骤上。我曾尝试在另一台同样使用16Gb内存的笔记本电脑上运行相同的代码,但我遇到了相同的问题。现在的方法似乎是创建一个额外的维度(即,(n\u行,vocab\u大小,句子长度)
),然后对每个句子进行求和,以获得每个单词的出现次数。它实际上不是一个三维数组,因为您正在使用pd.DataFrame.stack()
将一个维度转换为第二个索引,但它使用的内存量相同。创建额外维度的方法是在数据框架之外创建单词词典,并使用该词典统计每个文档中的单词。到目前为止,所有的解决方案都是这样做的。当我调用dictionary时,dictionary是空的。id2token
它会返回一个空的dictionaryDid您运行此行并阅读我的注释吗dictionary.id2token[0]#id2token是惰性的,因此需要调用它一次才能在内存中创建它
是的,我运行了这行,但它说dictionary是空的。它在第三行崩溃,当我调用dictionary.id2token时,它返回一个空的dictionary{}
,并且索引0不存在
import gensim
from gensim import corpora
dictionary = corpora.Dictionary(df_balanced_features.tolist())
dummy_encoded = df_balanced_features.apply(lambda doc: pd.Series(dict(dictionary.doc2bow(doc)))).fillna(0).astype(int)
dictionary.id2token[0] # id2token is lazy so you need to call it once to create it in memory
dummy_encoded.rename(columns=dictionary.id2token, inplace=True)
from collections import Counter
import pandas as pd
data = [["one", "home", "dark"],
["hello", "gamma", "hello"],
["five", "tango", "bravo"]]
words = ( Counter(d) for d in data )
df = pd.DataFrame(words, dtype="Int8").fillna(0).sort_index().sort_index(axis=1)
print(df)
bravo dark five gamma hello home one tango
0 0 1 0 0 0 1 1 0
1 0 0 0 1 2 0 0 0
2 1 0 1 0 0 0 0 1