增加列表列表的 Pythonic 方式
The Pythonic way to grow a list of lists
我有一个大文件 (2GB) 的分类数据(主要是 "Nan"-- 但在这里和那里填充了实际值)太大而无法读入单个数据框。我很难想出一个对象来存储每列的所有唯一值(这是我的目标——最终我需要将其分解以进行建模)
我最后做的是将文件分块读取到数据框中,然后获取每一列的唯一值并将它们存储在列表列表中。我的解决方案有效,但似乎最不符合 Pythonic——在 Python(3.5 版)中是否有更简洁的方法来完成此操作。我知道列数 (~2100)。
import pandas as pd
#large file of csv separated text data
data=pd.read_csv("./myratherlargefile.csv",chunksize=100000, dtype=str)
collist=[]
master=[]
i=0
initialize=0
for chunk in data:
#so the first time through I have to make the "master" list
if initialize==0:
for col in chunk:
#thinking about this, i should have just dropped this col
if col=='Id':
continue
else:
#use pd.unique as a build in solution to get unique values
collist=chunk[col][chunk[col].notnull()].unique().tolist()
master.append(collist)
i=i+1
#but after first loop just append to the master-list at
#each master-list element
if initialize==1:
for col in chunk:
if col=='Id':
continue
else:
collist=chunk[col][chunk[col].notnull()].unique().tolist()
for item in collist:
master[i]=master[i]+collist
i=i+1
initialize=1
i=0
之后,我对所有唯一值的最终任务如下:
i=0
names=chunk.columns.tolist()
for item in master:
master[i]=list(set(item))
master[i]=master[i].append(names[i+1])
i=i+1
因此 master[i] 给了我列名,然后是唯一值列表——粗略但它确实有效——我主要关心的是尽可能以 "better" 方式构建列表。
我建议使用 collections.defaultdict(set)
而不是 list
的 list
。
假设你从
开始
uniques = collections.defaultdict(set)
现在循环可以变成这样:
for chunk in data:
for col in chunk:
uniques[col] = uniques[col].union(chunk[col].unique())
注意:
defaultdict
总是有一个 set
代表 uniques[col]
(这就是它的用途),所以你可以跳过 initialized
和东西。
对于给定的 col
,您只需使用当前集合(最初为空,但无关紧要)和新的唯一元素的并集更新条目。
编辑
正如 Raymond Hettinger 所说(谢谢!),最好使用
uniques[col].update(chunk[col].unique())
我有一个大文件 (2GB) 的分类数据(主要是 "Nan"-- 但在这里和那里填充了实际值)太大而无法读入单个数据框。我很难想出一个对象来存储每列的所有唯一值(这是我的目标——最终我需要将其分解以进行建模)
我最后做的是将文件分块读取到数据框中,然后获取每一列的唯一值并将它们存储在列表列表中。我的解决方案有效,但似乎最不符合 Pythonic——在 Python(3.5 版)中是否有更简洁的方法来完成此操作。我知道列数 (~2100)。
import pandas as pd
#large file of csv separated text data
data=pd.read_csv("./myratherlargefile.csv",chunksize=100000, dtype=str)
collist=[]
master=[]
i=0
initialize=0
for chunk in data:
#so the first time through I have to make the "master" list
if initialize==0:
for col in chunk:
#thinking about this, i should have just dropped this col
if col=='Id':
continue
else:
#use pd.unique as a build in solution to get unique values
collist=chunk[col][chunk[col].notnull()].unique().tolist()
master.append(collist)
i=i+1
#but after first loop just append to the master-list at
#each master-list element
if initialize==1:
for col in chunk:
if col=='Id':
continue
else:
collist=chunk[col][chunk[col].notnull()].unique().tolist()
for item in collist:
master[i]=master[i]+collist
i=i+1
initialize=1
i=0
之后,我对所有唯一值的最终任务如下:
i=0
names=chunk.columns.tolist()
for item in master:
master[i]=list(set(item))
master[i]=master[i].append(names[i+1])
i=i+1
因此 master[i] 给了我列名,然后是唯一值列表——粗略但它确实有效——我主要关心的是尽可能以 "better" 方式构建列表。
我建议使用 collections.defaultdict(set)
而不是 list
的 list
。
假设你从
开始uniques = collections.defaultdict(set)
现在循环可以变成这样:
for chunk in data:
for col in chunk:
uniques[col] = uniques[col].union(chunk[col].unique())
注意:
defaultdict
总是有一个set
代表uniques[col]
(这就是它的用途),所以你可以跳过initialized
和东西。对于给定的
col
,您只需使用当前集合(最初为空,但无关紧要)和新的唯一元素的并集更新条目。
编辑
正如 Raymond Hettinger 所说(谢谢!),最好使用
uniques[col].update(chunk[col].unique())