gpt4 book ai didi

python - 如何加速 LabelEncoder 将分类变量重新编码为整数

转载 作者:太空狗 更新时间:2023-10-30 00:54:15 24 4
gpt4 key购买 nike

我有一个很大的 csv,每行有两个字符串,格式如下:

g,k
a,h
c,i
j,e
d,i
i,h
b,b
d,d
i,a
d,h

我阅读了前两列并将字符串重新编码为整数,如下所示:

import pandas as pd
df = pd.read_csv("test.csv", usecols=[0,1], prefix="ID_", header=None)
from sklearn.preprocessing import LabelEncoder

# Initialize the LabelEncoder.
le = LabelEncoder()
le.fit(df.values.flat)

# Convert to digits.
df = df.apply(le.transform)

此代码来自https://stackoverflow.com/a/39419342/2179021 .

该代码工作得很好,但当 df 很大时速度很慢。我为每个步骤计时,结果令我惊讶。

  • pd.read_csv 大约需要 40 秒。
  • le.fit(df.values.flat) 大约需要 30 秒
  • df = df.apply(le.transform) 大约需要 250 秒。

有什么方法可以加快这最后一步吗?感觉应该是最快的一步了!


在具有 4GB RAM 的计算机上重新编码步骤的更多计时

maxymoo 下面的答案很快,但没有给出正确答案。以问题顶部的示例 csv 为例,它将其转换为:

   0  1
0 4 6
1 0 4
2 2 5
3 6 3
4 3 5
5 5 4
6 1 1
7 3 2
8 5 0
9 3 4

请注意,“d”在第一列中映射到 3,而在第二列中映射到 2。

我尝试了 https://stackoverflow.com/a/39356398/2179021 中的解决方案并获得以下信息。

df = pd.DataFrame({'ID_0':np.random.randint(0,1000,1000000), 'ID_1':np.random.randint(0,1000,1000000)}).astype(str)
df.info()
memory usage: 7.6MB
%timeit x = (df.stack().astype('category').cat.rename_categories(np.arange(len(df.stack().unique()))).unstack())
1 loops, best of 3: 1.7 s per loop

然后我将数据帧大小增加了 10 倍。

df = pd.DataFrame({'ID_0':np.random.randint(0,1000,10000000), 'ID_1':np.random.randint(0,1000,10000000)}).astype(str) 
df.info()
memory usage: 76.3+ MB
%timeit x = (df.stack().astype('category').cat.rename_categories(np.arange(len(df.stack().unique()))).unstack())
MemoryError Traceback (most recent call last)

此方法似乎使用了太多 RAM 来尝试转换它崩溃的这个相对较小的数据帧。

我还使用具有 1000 万行的较大数据集对 LabelEncoder 进行计时。它运行时没有崩溃,但仅拟合线就花了 50 秒。 df.apply(le.transform) 步骤耗时约 80 秒。

我怎样才能:

  1. 大致了解 maxymoo 的回答速度和 LabelEncoder 的大致内存使用情况,但当数据帧有两列时,这会给出正确的答案。
  2. 存储映射以便我可以将其重复用于不同的数据(就像 LabelEncoder 允许我做的那样)?

最佳答案

看起来使用 pandas category 数据类型会快得多;在内部,它使用哈希表,而 LabelEncoder 使用排序搜索:

In [87]: df = pd.DataFrame({'ID_0':np.random.randint(0,1000,1000000), 
'ID_1':np.random.randint(0,1000,1000000)}).astype(str)

In [88]: le.fit(df.values.flat)
%time x = df.apply(le.transform)
CPU times: user 6.28 s, sys: 48.9 ms, total: 6.33 s
Wall time: 6.37 s

In [89]: %time x = df.apply(lambda x: x.astype('category').cat.codes)
CPU times: user 301 ms, sys: 28.6 ms, total: 330 ms
Wall time: 331 ms

编辑:这是一个您可以使用的自定义转换器类(您可能不会在官方 scikit-learn 版本中看到它,因为维护者不希望将 pandas 作为依赖)

import pandas as pd
from pandas.core.nanops import unique1d
from sklearn.base import BaseEstimator, TransformerMixin

class PandasLabelEncoder(BaseEstimator, TransformerMixin):
def fit(self, y):
self.classes_ = unique1d(y)
return self

def transform(self, y):
s = pd.Series(y).astype('category', categories=self.classes_)
return s.cat.codes

关于python - 如何加速 LabelEncoder 将分类变量重新编码为整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39475187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com