将csv标头和相应的文件路径合并到新文件中

时间:2018-07-03 10:22:21

标签: python parsing

我不确定如何“破解”以下Python-nut。因此,我希望一些经验丰富的Python专家可以将我推向正确的方向。

我得到的: 几个包含许多csv文件的目录

例如:

/home/Date/Data1 /home/Date/Data2 /home/Date/Data3/sub1 /home/Date/Data3/sub2

我想要的东西: 一个文件,其中包含每个文件的“拆分”路径,后跟相应文件的变量(=行/标题)。像这样:

home /t Date /t Data1 /t "variable1" "variable2" "variable3" ...
home /t Date /t Data2 /t "variable1" "variable2" "variable3" ...
home /t Date /t Data3 /t sub1 /t  "variable1" "variable2" "variable3" ...
home /t Date /t Data3 /t sub2 /t  "variable1" "variable2" "variable3" ...

我现在在哪里?:第一步是弄清楚如何打印单个csv文件的第一行(变量)(我使用test.txt文件进行测试)

# print out variables of a single file:
import csv
with open("test.txt") as f:
    reader = csv.reader(f)
    i = next(reader)

    print(i)

第二步是弄清楚如何在包含目录的子文件夹中打印csv文件的路径。这就是我的结局:

import os

# Getting the current work directory (cwd)
thisdir = os.getcwd()

# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
    for file in f:
        if ".csv" in file:
            print(os.path.join(r, file))

打印:

/home/Date/Data1/file1.csv
/home/Date/Data1/file2.csv
/home/Date/Data2/file1.csv
/home/Date/Data2/file2.csv
/home/Date/Data2/file3.csv
/home/Date/Data3/sub1/file1.csv
/home/Date/Data3/sub2/file1.csv
/home/Date/Data3/sub2/file2.csv

我被困在哪里?:我正在努力弄清楚如何从这里获得帮助,非常感谢在正确方向上提出的任何想法,方法等!

干杯B

#####更新#####

受蒂姆·皮茨克(Tim Pietzcker)有用评论的启发,我走了很长一段路(谢谢蒂姆!)。 但是我无法使output.write和join部分起作用,因此代码略有不同。现在的新问题是将两个列表“合并”为两个单独的列,并用逗号作为定界符(我想创建一个csv文件)。由于我被困住了,我再次想看看这里有经验的python'ers是否有任何好的建议?

#!/usr/bin/python
import os
import csv
thisdir = os.getcwd()

# Extract file-paths and append them to "csvfiles"
for r, d, f in os.walk(thisdir):        # r=root, d=directories, f = files
    for file in f:
        if ".csv" in file:
            csvfiles.append(os.path.join(r, file))

# get each file-path on new line + convert to list of str
filepath = "\n".join(["".join(sub) for sub in csvfiles])
filepath = filepath.replace(".csv", "")  # remove .csv
filepath = filepath.replace("/", ",")    # replace / with ,

结果:

,home,Date,Data1,file1
,home,Date,Data1,file2
,home,Date,Data1,file3
... and so on

然后转到标题:

# Create header-extraction function:
def get_csv_headers(filename):
    with open(filename, newline='') as f:
        reader = csv.reader(f)
        return next(reader)

# Create empty list for headers
headers=[]

# Extract headers with the function and append them to "headers" list
for l in csvfiles:
    headers.append(get_csv_headers(l))

# Create file with headers
headers = "\n".join(["".join(sublst) for sublst in headers]) # new lines + str conversion
headers = headers.replace(";", ",") # replace ; with ,

结果:

variable1,variable2,variable3
variable1,variable2,variable3,variable4,variable5,variable6
variable1,variable2,variable3,variable4
and so on..

我现在想要的是:像这样的csv:

home,Date,Data1,file1,variable1,variable2,variable3
home,Date,Data1,file2,variable1,variable2,variable3,variable4,variable5,variable6
home,Date,Data1,file3, variable1,variable2,variable3,variable4

例如:

with open('text.csv', 'w') as f:
    writer = csv.writer(f, delimiter=',')
    writer.writerows(zip(filepath,headers))

导致:

",",v
h,a
o,r
m,i,
e,a
and so on..

任何想法和正确方向的推动都非常欢迎!

2 个答案:

答案 0 :(得分:0)

这看起来很有希望;您已经完成了大部分工作。

我要做的是

  1. 在列表中收集所有CSV文件名。因此,与其打印文件名,不如在csvfiles=[]循环之前创建一个空列表(os.walk()),然后执行类似csvfiles.append(os.path.join(r, file))的操作。
  2. 然后,遍历这些文件名,将每个文件名传递给当前用于读取test.txt的例程。如果将其放在函数中,则可能如下所示:

def get_csv_headers(filename):
    with open(filename, newline="") as f:
        reader = csv.reader(f)
        return next(reader)
  1. 现在,您可以将拆分的文件名写入新文件并添加标题。我有点质疑您的文件格式-为什么用制表符将行的一部分分开,而用空格(和引号)将其余部分分开?如果您坚持要这样做,可以使用类似的方法

output.write("\t".join(filename.split("\\"))
output.write("\t")
output.write(" ".join(['"{}"'.format(header) for header in get_csv_headers(filename)])

,但是您可能需要重新考虑这种方法。 JSON之类的标准格式可能更具可读性和可移植性。

答案 1 :(得分:0)

关于您的修改:建议您不要在过程的早期就将所有内容都转换为字符串。将数据保持为结构化格式更有意义,并允许设计用于处理结构化数据的模块完成其余工作。因此您的程序可能看起来像这样:

#!/usr/bin/python
import os
import csv
thisdir = os.getcwd()

# Extract file-paths and append them to "csvfiles"
for r, d, f in os.walk(thisdir):        # r=root, d=directories, f = files
    for file in f:
        if ".csv" in file:
            csvfiles.append(os.path.join(r, file))

(直接从您的问题中获取)这给您留下了CSV文件名列表。

现在让我们阅读这些文件。从问题脚本中,您的CSV文件似乎实际上是用分号分隔的,而不是用逗号分隔的。这在欧洲很常见(因为逗号需要用小数点表示),但是Python需要告知:

# Create header-extraction function:
def get_csv_headers(filename):
    with open(filename, newline='') as f:
        reader = csv.reader(f, delimiter=";")  # semicolon-separated files!
        return next(reader)

# Create empty list for headers
headers=[]

# Extract headers with the function and append them to "headers" list
for l in csvfiles:
    headers.append(get_csv_headers(l))

现在headers是一个包含许多子列表的列表(根据需要,这些子列表将所有标头作为单独的项目包含在内)。

我们不要试图将所有内容放在一行上;最好保持可读性:

with open('text.csv', 'w', newline="") as f:
    writer = csv.writer(f, delimiter=',') # maybe use semicolon again??
    for path, header in zip(csvfiles, headers):
        writer.writerow(list(path.split("\\")) + header)

如果所有路径均以\开头,则也可以使用

        writer.writerow(list(path.split("\\")[1:]) + header)

避免在每一行的开头留空字段。

相关问题