在python中迭代大型csv文件中的行的最佳方法,写入新的

Posted

技术标签:

【中文标题】在python中迭代大型csv文件中的行的最佳方法,写入新的【英文标题】:Best way to iterate over rows in large csv file in python, write to new one 【发布时间】:2020-08-28 16:02:24 【问题描述】:

我是一个相对的 python 新手,试图有效地查看约 800 万行的大型 csv 文件。

我有一个 6 列的 csv:

+-------+-------+--------+-------+--------+----------+
| Gene1 | Start |  End   | Gene2 | Start  |   End    |
+-------+-------+--------+-------+--------+----------+
| gyrA  |    33 |    193 | dnaB  |    844 |      965 |
| rpoS  |   152 |    190 | ldh   |    200 |      264 |
| gbpC  |   456 |    500 | bgl   |   1222 |    14567 |
+-------+-------+--------+-------+--------+----------+

.....等 8,000,000 行

我想要做的是比较 Gene2 的开始和结束是否在某个范围内 +/- Gene1 的开始和结束。例如,我想查看 Gene1 的结尾是否在 Gene2 开头的 20 以内。然后,我想将所有行写入新的 csv 文件。

代码: 如果 Gene1 的结尾在 Gene2 开头的 +/- 20 范围内,则将整行追加到新文件中

输出:

+-------+-------+--------+-------+-------+--------+
| Gene1 | Start |  End   | Gene2 | Start |  End   |
+-------+-------+--------+-------+-------+--------+
| rpoS  |   152 |    190 | ldh   |   200 |    264 |
+-------+-------+--------+-------+-------+--------+

对于 python 新手来说,最有效的方法是什么?我将不得不在多个 csv 上多次运行代码,所以我担心速度。我尝试过使用 pandas,但似乎 itterrows() 函数不是提高效率的建议方法.我认为我可以使用 csv 阅读器轻松完成此操作,但我不确定运行可能需要多长时间。

感谢您帮助解决此问题!

【问题讨论】:

【参考方案1】:

我们可以使用chunksize 来使用生成器表达式并一次处理多行并将其写入csv。分块执行此操作将使您免于耗尽所有内存。

另一种选择是使用Dask,您可以继续阅读。

首先,我们创建一个空白 csv,其中包含要写入的目标标头。

header_df = pd.read_csv(yourfile,nrows=1)

header_df.iloc[:0].to_csv('target_file',index=False)

chunksize = 5 * 10000 #50k rows.

for chunk in pd.read_csv(your_file,chunksize=chunksize):
#your etl logic.
#assuming your final variable is called target df.
    target_df.to_csv(target_file, mode='a', header=False,index=False)

【讨论】:

【参考方案2】:

许多 Pandas 操作都是矢量化的。自己快速编写一些性能更高的东西是很困难的:

df = pd.read_csv('large.csv')

  Gene1  Start  End Gene2  Start.1  End.1
0  gyrA     33  193  dnaB      844    965
1  rpoS    152  190   ldh      200    264
2  gbpC    456  500   bgl     1222  14567

返回布尔序列的条件:

abs(df.End - df['Start.1']) <= 20

0    False
1     True
2    False

通过布尔系列过滤数据框:

df[abs(df.End - df['Start.1']) <= 20]

  Gene1  Start  End Gene2  Start.1  End.1
1  rpoS    152  190   ldh      200    264

查看Getting Started 页面了解更多信息。

【讨论】:

以上是关于在python中迭代大型csv文件中的行的最佳方法,写入新的的主要内容,如果未能解决你的问题,请参考以下文章

将特定行的csv读入php

如何将每个给定长度的行的 Bigquery 表提取到 Google Storage 中的 csv 文件?

将CSV文件数据读取为命名元组行的pythonic方法是啥?

我有一个大型 CSV 文件,其中包含单个列中的信息。如何使用 python 在 excel 中复制“文本到列”任务? [复制]

如何在python中对没有标题的大型csv信号文件进行分类?

Python Pandas read_csv 跳过行但保留标题