python:在分块读取 csv 时将 pandas 分类值转换为整数
python: convert pandas categorical values to integer when reading csv in chunks
我有一个包含 1000 列的大型 csv 文件,第 0 列是一个 id,其他列是分类的。我想将它们转换为整数值,以便将它们用于数据分析。如果我有足够的内存,第一种 "dummy" 方法会起作用:
filename_cat_train = "../input/train_categorical.csv"
df = pd.read_csv(filename_cat_train, dtype=str)
for column in df.columns[1:]:
df[column] = df[column].astype('category')
columns = df.select_dtypes(['category']).columns
df[columns] = df[columns].apply(lambda x: x.cat.codes)
df.to_csv("../input/train_categorical_rawconversion.csv", index=False)
但它持续时间很长,绝对不是解决任务的明智方法。
我可以按块加载数据文件,然后在使用上述方法转换为 int 值后合并。但是,当以块(甚至 100k 大)加载时,并非所有类别都出现在我的数据中。这意味着,在第一个块中具有值 T10、T11、T13,在第二个块中具有值 T10、T11、T12,块中的类别出现不同的值。
对我来说最佳方式是:
0. 创建分类和对应的 int 值的列表(只有大约 100 个,很容易从数据中检索它们)
1.分块加载数据
2.替换列表中的值
3.保存每个块,然后将它们组合起来。
我怎样才能有效地执行这些步骤?也许存在更好的方法?
谢谢!
Update1: 相同类型的分类数据。它们是 T12、T45689、A3333 等键。csv 文件是这样的:
4,T12,A44,B3333,
在这种情况下,看来确实可以采用两次通过的方案。
开始于
import pandas as pd
data=pd.read_csv(my_file_name, chunksize=my_chunk_size)
你可以这样做:
import collections
uniques = collections.defaultdict(list)
for chunk in data:
for col in chunk:
uniques[col].update(chunk[col].unique())
此时,uniques 应该将每个列名称映射到其中出现的唯一项目。要翻译成地图,您现在可以使用
for col in uniques:
uniques[col] = dict((e[1], e[0]) for e in enumerate(uniques[col]))
现在再次阅读文件,并使用对应的地图翻译每一列(参见 here。)
如果您的列都包含来自 "the same dictionary" 的键,您可以执行以下操作:
从以下开始
import pandas as pd
data=pd.read_csv(my_file_name, chunksize=my_chunk_size)
你可以这样做:
uniques = set([])
for chunk in data:
for col in cols:
uniques.update(chunk[col].unique())
此时,uniques 应该包含出现在 DataFrame 中的唯一项目。要翻译成地图,您现在可以使用
uniques = dict((e[1], e[0]) for e in enumerate(uniques))
现在,再次加载DataFrame,并使用pd.DataFrame.replace。
我有一个包含 1000 列的大型 csv 文件,第 0 列是一个 id,其他列是分类的。我想将它们转换为整数值,以便将它们用于数据分析。如果我有足够的内存,第一种 "dummy" 方法会起作用:
filename_cat_train = "../input/train_categorical.csv"
df = pd.read_csv(filename_cat_train, dtype=str)
for column in df.columns[1:]:
df[column] = df[column].astype('category')
columns = df.select_dtypes(['category']).columns
df[columns] = df[columns].apply(lambda x: x.cat.codes)
df.to_csv("../input/train_categorical_rawconversion.csv", index=False)
但它持续时间很长,绝对不是解决任务的明智方法。
我可以按块加载数据文件,然后在使用上述方法转换为 int 值后合并。但是,当以块(甚至 100k 大)加载时,并非所有类别都出现在我的数据中。这意味着,在第一个块中具有值 T10、T11、T13,在第二个块中具有值 T10、T11、T12,块中的类别出现不同的值。
对我来说最佳方式是: 0. 创建分类和对应的 int 值的列表(只有大约 100 个,很容易从数据中检索它们) 1.分块加载数据 2.替换列表中的值 3.保存每个块,然后将它们组合起来。
我怎样才能有效地执行这些步骤?也许存在更好的方法? 谢谢!
Update1: 相同类型的分类数据。它们是 T12、T45689、A3333 等键。csv 文件是这样的: 4,T12,A44,B3333,
在这种情况下,看来确实可以采用两次通过的方案。
开始于
import pandas as pd
data=pd.read_csv(my_file_name, chunksize=my_chunk_size)
你可以这样做:
import collections
uniques = collections.defaultdict(list)
for chunk in data:
for col in chunk:
uniques[col].update(chunk[col].unique())
此时,uniques 应该将每个列名称映射到其中出现的唯一项目。要翻译成地图,您现在可以使用
for col in uniques:
uniques[col] = dict((e[1], e[0]) for e in enumerate(uniques[col]))
现在再次阅读文件,并使用对应的地图翻译每一列(参见 here。)
如果您的列都包含来自 "the same dictionary" 的键,您可以执行以下操作:
从以下开始
import pandas as pd
data=pd.read_csv(my_file_name, chunksize=my_chunk_size)
你可以这样做:
uniques = set([])
for chunk in data:
for col in cols:
uniques.update(chunk[col].unique())
此时,uniques 应该包含出现在 DataFrame 中的唯一项目。要翻译成地图,您现在可以使用
uniques = dict((e[1], e[0]) for e in enumerate(uniques))
现在,再次加载DataFrame,并使用pd.DataFrame.replace。