【问题标题】:How to perform a CSV concatenation in Python as effectively as this awk command?如何在 Python 中像这个 awk 命令一样有效地执行 CSV 连接?
【发布时间】:2021-04-01 14:10:07
【问题描述】:

我正在尝试在 Python 中自动执行文件连接过程,该过程与我一直使用的 bash 命令行过程一样有效。我的 bash CLI 进程使用 awk 来合并文件,而我尝试使用的 Python 使用 pandas

例如,假设我有一个包含多个名为 part_0.csvpart_1.csv、...、part_n.csv 的 CSV 文件的目录。每个文件的第一行都包含一个标题。我为此使用的 bash CLI 命令:

$ cd directory_containing_csv_files
$ mv part_0.csv merged.csv
$ awk 'FNR > 1' part*.csv > merged.csv

Python/pandas 代码做同样的事情,但是当总大小变大时会发出嘶哑的声音:

# read all the CSVs into a single file using concatenation (assumes same schema for all files)
combined_df = pd.concat([pd.read_csv(pth, header=0) for pth in csv_paths])

# write as single CSV file
combined_df.to_csv(dest_path, index=False, header=True)

Python 代码在达到大小限制之前似乎运行良好(相关机器有 16GB RAM)。无论最终文件大小如何,bash 命令行处理都没有失败。

也许还有另一种不使用 pandas 的 Python 方法更节省内存?

【问题讨论】:

  • 您可以随时使用os.system()调用awk
  • 是的,使用csv 模块。
  • 同意,这是最简单的,虽然它不是可移植的(在 Windows 机器上找不到 awk)。
  • 这能回答你的问题吗? how to merge 200 csv files in Python
  • 实际上,您不需要 csv 模块,因为您不必实际解析 csv。

标签: python pandas bash awk


【解决方案1】:

您可以尝试to_csv 与文件流:

first = True

# open a file
with open('a.csv', 'w') as f:

    # loop through the csv's
    for pth in csv_paths:
        df = pd.read_csv(pth)
        
        # write to the stream
        # only write the first header
        df.to_csv(f, header=first, index=False)

        # toggle the first header
        if first: first = False

【讨论】:

  • 感谢@Quang Hong。也许 first 变量应该被初始化为 True,并在切换条件中设置为 False?
  • @JamesAdams 是的,完全正确。更新。谢谢。
【解决方案2】:

也许还有另一种不使用 pandas 的 Python 方法更节省内存?

使用pandas 意味着您正在解析您的csvs,如果您只想连接除第一行之外的所有行,这不是必需的。您的任务似乎适合fileinput 内置模块。创建文件merger.py如下:

import fileinput
for line in fileinput.input():
    if not fileinput.isfirstline():
        print(line, end='')

然后替换

awk 'FNR > 1' part*.csv > merged.csv

使用

python3 merger.py part*.csv > merged.csv

请注意,fileinput.input 确实保留了换行符,print 函数默认在末尾添加换行符,所以我通知print 不要这样做(end=''),否则你会得到多余的换行符(空白行在您的数据之间交错)。

(在 python 3.7.3 中测试)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-12
    • 2017-05-28
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多