【问题标题】:How to copy columns from several csv files into a single csv file with python?如何使用 python 将多个 csv 文件中的列复制到单个 csv 文件中?
【发布时间】:2014-03-11 13:34:41
【问题描述】:

我在名为 path 的目录中有几个单列 csv 文件,我想将所有这些列合并到一个文件中,并将该文件作为 out.csv 存储在名为 repsim 的目录中。 这是我的代码:

假设我已经有了filesfin=files[0]的列表

def ajouter (fin, files, out, path, repsim, delim=';'):
    fic=os.path.join(path,fin)
    with open(fic, 'rb') as fr:
        print fic + " est overt"
        tout=[]
        for i in range(1, len(files)):
            fil=files[i]
            print fil + " en cours -------------"
            f=os.path.join(path,fil)
            with open(f, 'rb') as fi:
                fr_reader = csv.reader(fr, delimiter=delim)
                fi_reader = csv.reader(fi, delimiter=delim) 

                for row1, row2 in zip(fr_reader, fi_reader):
                    row2.append(row1[-1])
                    tout.append(row2)

        fout=os.path.join(repsim,out)
        with open(fout, 'ab') as output: 
            writer = csv.writer(output, delimiter=delim)
            writer.writerows(tout)

这段代码只给了我一个两列文件,由files[0] 的列和文件中最后一个文件的列组成。

【问题讨论】:

  • 您要堆叠列吗?你想并排保持列吗?如果两个文件包含同名的列,会发生什么?您能否提供两个示例输入 CSV 文件和相应的预期输出文件?
  • 顺便说一句,我会为此使用pandas。它可以读取 CSV 文件,然后堆叠和/或合并数据集并仅在几行中写入一个新的 CSV 文件。
  • 我希望列并排,每个文件都有一个唯一的列名。
  • 例如,file1=>column bw64 有 10 行,file2=>column hop64 也有 10 行,file3=>column recall64 也有 10 行

标签: python csv


【解决方案1】:

虽然这对您来说可能是一个有趣的练习,但需要重新发明轮子。这是直接使用例如pandas:

import pandas as pd
dataframes = [pd.read_csv(p) for p in ("data1.csv", "data2.csv")]
merged_dataframe = pd.concat(dataframes, axis=1)
merged_dataframe.to_csv("merged.csv", index=False)

输入:

$ cat data1.csv 
data1
a
b
c
d
$ cat data2.csv 
data2
p
q
r
s

输出:

$ cat merged.csv 
data1,data2
a,p
b,q
c,r
d,s

【讨论】:

  • pandas 模块打印错误:它说 ValueError:传递值的形状是 (1,42) 索引意味着 (1,24)。我不知道这个错误,这是我第一次使用 pandas。
  • pandas 仍然是要走的路,该错误很可能很容易修复。如您所见,最小的示例有效。可能您的数据与我的最小示例中的数据在某些方面存在显着差异。找出差异并告诉我们。此外,您应该显示代码和回溯。
  • 这就是我使用你的代码的方式:def merge (files, out, path, repsim): dataframes = [pd.read_csv(os.path.join(path,p)) for p in files] merged_dataframe = pd.concat(dataframes, axis=1) merged_dataframe.to_csv(os.path.join(repsim,out), index=False)
  • 我的文件如下:file1=> 一列具有唯一名称 Cname(例如 bw64)和 10 行具有 int 值。
  • 可能错误是由我的文件分隔符引起的!在我的 csv 文件中,我使用的分隔符是 ';',而不是默认的 ','
【解决方案2】:

itertools.izip 非常适合这种事情,因为它不需要您将文件读入内存。它的工作方式与zip 类似,只是它返回的是迭代器而不是元组列表。像下面这样的东西应该可以工作。

import csv
import os
from itertools import izip, chain

def ajouter(files, out, path, repsim, delim=';'):

    try:
        open_files = [open(os.path.join(path, file_)) for file_ in files]
        readers = (csv.reader(f, delimiter=delim) for f in open_files)
        merged_cols = (tuple(chain.from_iterable(row)) for row in izip(*readers))


        with open(os.path.join(repsim, out), 'wb') as output:
            writer = csv.writer(output, delimiter=delim)
            writer.writerows(merged_cols)
    finally:
        for open_file in open_files:
            open_file.close()

【讨论】:

  • 它可以工作,但在输出文件中,列值的格式如下 ['0.65']。你能帮我修改一下吗?
猜你喜欢
  • 2019-11-08
  • 1970-01-01
  • 2022-01-04
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
相关资源
最近更新 更多