使用索引列表访问项目列表
Posted
技术标签:
【中文标题】使用索引列表访问项目列表【英文标题】:Access list of items with list of indices 【发布时间】:2012-02-18 23:32:06 【问题描述】:考虑从大型 csv 文件 (80 MB) 返回的大型命名项目列表(第一行),其中可能有中断的间距
name_line = ['a',,'b',,'c' .... ,,'cb','cc']
我正在逐行读取剩余的数据,我只需要处理具有相应名称的数据。数据可能看起来像
data_line = ['10',,'.5',,'10289' .... ,,'16.7','0']
我尝试了两种方法。一个是从读取的每一行中弹出空列
blnk_cols = [1,3, ... ,97]
while data:
...
for index in blnk_cols: data_line.pop(index)
另一个正在编译与 L1 中的名称关联的项目
good_cols = [0,2,4, ... ,98,99]
while data:
...
data_line = [data_line[index] for index in good_cols]
在我使用的数据中,肯定会有更多的好行而不是坏行,尽管它可能高达一半。
我使用 cProfile 和 pstats 包来确定我最薄弱的速度链接,这表明 pop 是当前最慢的项目。我切换到列表组合,时间几乎翻了一番。
我想一种快速的方法是对数组进行切片,只检索好的数据,但这对于具有交替空白和好的数据的文件来说会很复杂。
我真正需要的是能够做到
data_line = data_line[good_cols]
有效地将索引列表传递到列表中以取回这些项目。 现在,对于一个 10 MB 的文件,我的程序在大约 2.3 秒内运行,而 pop 大约需要 0.3 秒。
是否有更快的方法来访问列表中的某些位置。在 C 中,它只是取消引用指向数组中正确索引的指针数组。
补充: 读取前文件中的 name_line
a,b,c,d,e,f,g,,,,,h,i,j,k,,,,l,m,n,
读取和拆分后的name_line(",")
['a','b','c','d','e','f','g','','','','','h','i','j','k','','','','l','m','n','\n']
【问题讨论】:
你在用 data_line 做什么?你只是在迭代它吗?您是否将其放入另一个数据结构中? 另外,你试过发电机吗? “考虑从一个大的 csv 文件返回一个大列表”?您是否将整个文件读入一个列表?为什么?为什么不单独处理每一行? 我正在阅读的文件是一个更高频率的文件(即10 hz)。我正在读取行并在 x 秒间隔内累积和平均所有值并将其写回文件中。即从 10 hz 到 1 hz 将累积 10 个数据值(从 0 到 1 秒)平均它们并将单个数据行输出到平均数据范围的地板(时间)的文件中 我正在单独处理每一行。为清楚起见进行了编辑 【参考方案1】:尝试生成器表达式,
data_line = (data_line[i] for i in good_cols)
也在这里阅读 Generator Expressions vs. List Comprehension
正如最佳答案告诉您的那样:“基本上,如果您所做的只是迭代一次,请使用生成器表达式”。
所以你应该从中受益。
【讨论】:
哪个更快取决于你用它做什么。生成器的优点是它是惰性的,因此您不会为仅访问一次的项目分配大量内存。 @Marcin。是的,澄清了我的答案。 重构了我的所有代码以适应生成器表达式。我遍历每条数据线一次进行处理(使用具有适当索引的生成器,而不是最初弹出空白值)。代码运行慢了大约 0.3 秒,因为我需要为每个数据行重新创建生成器表达式。 @PaulSeeb 我很困惑。 创建生成器表达式不应该花费任何时间。 这个文件有 25000 行。我需要为每一行创建一个新的生成器来处理该行中的所有数据,除非我可以“重置”每一行的生成器。我对此进行了一些研究,发现这是不可能的。以上是关于使用索引列表访问项目列表的主要内容,如果未能解决你的问题,请参考以下文章