文本处理和 pd.get_dummies() 编码消耗大量 RAM

Text Processing and pd.get_dummies() Encoding Consumes huge amount of RAM

我有一个由列表中的标记化词和词干词组成的数据集,我正在使用 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)

计算系列中每个列表中每个字符串的频率(类似于 level=0)

  total_rows = list()
    for column in unique_values:
      row = list()
      for values in df_balanced_features:
        number = values.count(column)
        row.append(number)
      total_rows.append(row)
    

移置 total_rows

    total_rows = np.array(total_rows)
    total_rows = total_rows.transpose()
    

创建一个类似于假人的DataFrame

    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)

这是一种使用内置集合 package 中的 Counter 的方法——它可能比您提供的解决方案占用更少的内存。我使用了 dtype="Int8",它是一个支持空 (NaN) 值的 8 位 pandas 整数类型。

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