【问题标题】:Combine CSV file data to one CSV file将 CSV 文件数据合并为一个 CSV 文件
【发布时间】:2013-04-17 05:43:32
【问题描述】:

我的 csv 文件分布在多个目录中,每个 csv 文件只有一列包含数据。我想要做的是读取所有这些文件并将每个文件的列放入 csv 文件中。最终的 csv 文件将以文件名作为其标题的列,并将其原始文件中的相应数据作为其列数据。

这是我在~/csv_files/ ls里面的目录结构

ab   arc  bat-smg   bn       cdo  crh      diq  es   fo   gd   haw  ia   iu   ki   ksh  lez  lv   mo   na      no   os   pih  rmy   sah  simple  ss   tet  tr   ur   war  zea
ace  arz  bcl       bo       ce   cs       dsb  et   fr   gl   he   id   ja   kk   ku   lg   map-bms  mr   nah     nov  pa   pl   rn    sc   sk      st   tg   ts   uz   wo   zh
af   as

每个目录都有两个 csv 文件,我想使用 os.walk() 函数,但我认为我对 os.walk 的理解是不正确的,这就是为什么我目前没有产生任何东西的原因。

import sys, os
import csv

root_path = os.path.expanduser(
    '~/data/missing_files')

def combine_csv_files(path):
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            for name in files:
                if name.endswith(".csv"):
                    csv_path = os.path.expanduser(root_path + name)
                    if os.path.exists(csv_path):
                        try:
                            with open(csv_path, 'rb') as f:
                                t = f.read().splitlines()
                                print t
                        except IOError, e:
                            print e

def main():
    combine_csv_files(root_path)

if __name__=="__main__":
    main()

我的问题是:

  1. 我在这里做错了什么?
  2. 我能否从另一个文件中读取一个 csv 列并将该数据作为一个列添加到另一个文件中,因为 csv 文件更依赖于行,并且行之间没有依赖关系。

最后我试图得到这样的 csv 文件,(这里是潜在的标题)

ab_csv_data_file1, ab_csv_data_file2, arc_csv_data_file1, arc_csv_data_file2

【问题讨论】:

  • print csv_path 添加到最里面的for 循环以确保路径符合您的预期
  • 你误用了 os.walk()

标签: python csv os.walk


【解决方案1】:

你错误地使用了 os.walk()

def combine_csv_files(path):
    for root, dirs, files in os.walk(path):
        for name in files:
            if name.endswith(".csv"):
                csv_path = os.path.join(root, name)
                try:
                    with open(csv_path, 'rb') as f:
                        t = f.read().splitlines()
                        print t
                except IOError, e:
                    print e

os.walk() 函数产生一个 3 元组(目录路径、目录名、文件名)。其中“dirpath”是当前行走目录的路径,“dirnames”是“dirpath”中的目录列表,“filenames”是“dirpath”中的文件列表。 “dirpath”可能是这里的“路径”,以及“路径”的任何子文件夹。

【讨论】:

  • 太棒了!谢谢,当我在新文件中写这个时如何访问目录名我希望目录名成为列标题
  • 更长的目录名称是“root”。如果您只想要最后一个目录名称,请使用 os.path.basename(root)。很高兴看到我的代码有帮助!
  • 刚刚更新了问题,以便对最终的 csv 有一个清晰的认识。谢谢,
  • @Null-Hypothesis 试试 name+os.path.basename(root)
【解决方案2】:

我不知道我是否明白你的意思。让你有多个文件夹,如“ab”、“arc”等。对于每个文件夹,它包含两个 CSV 文件。

如果我是对的,那么你就没有做正确的事。

def combine_csv_files(path):
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            for dirpath, sub_dirs, sub_files in os.walk('/'.join([path,dir])
                for name in sub_files:
                    if name.endswith(".csv"):
                        csv_path = os.path.expanduser(dirpath + name)
                        if os.path.exists(csv_path):
                            try:
                                with open(csv_path, 'rb') as f:
                                    t = f.read().splitlines()
                                    print t
                            except IOError, e:
                                print e

如果我是对的,上面的代码应该可以工作

【讨论】:

  • 个人觉得第二个os.walk没用。和OS独立,os.path.join优于'/'.join
  • os.path.join 更好我同意。但是,第二个 os.walk 是必要的。首先 os.walk 获取所有子目录。当您迭代每个子目录时,您将需要第二个 os.walk 来找出该子目录下的文件。我的意思是这种方法本身并不是最优的,但我猜这个想法是正确的。
猜你喜欢
  • 2018-03-30
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多