【发布时间】:2017-01-21 08:37:42
【问题描述】:
我有一个大 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 秒。
我该怎么做:
- 获得的结果大致与 maxymoo 的答案速度和 LabelEncoder 的内存使用量大致相同,但当数据帧有两列时,它会给出正确的答案。
- 存储映射,以便我可以将它用于不同的数据(就像 LabelEncoder 允许我做的那样)?
【问题讨论】:
-
您的 csv - 行和列有多大?你有多少个 le.class?
-
@wwii 大约 1000 万行和 100 万个 le.classes。
-
groupby....完成了什么? -
@wwii 它计算重复。
-
您使用的是哪个版本的 Python?
标签: python pandas scikit-learn