Python рекурсивно читает файлы cvs в каталоге дерева и добавляет один из двух столбцов в фрейм данных

У меня есть корневой каталог, который содержит сотни подпапок. Теперь я хочу прочитать файлы csv в каждой подпапке, их имена одинаковы, скажем, study.csv

После прочтения CSV-файлов я хочу создать фрейм данных для хранения части данных из этих CSV-файлов. Новый фрейм данных будет содержать 3 столбца. Один столбец — это столбец, который мы недавно создали для обозначения идентификатора CSV-файла, а два других столбца — это два столбца CSV-файла.

Например: Структура исходного CSV-файла:

row1....
row2....
row3....
row4: column1 column2 column3 column14 column5
row5:    1       2      3         4      5
row6:    2       4      2         1      10
row7:    3       8      9        11      23
...

Ожидаемый кадр данных, который я хочу:

New column       column3       column4
1                  3              4
1                  2              1
1                  2              1
1                  9              11

Таким образом, мы будем читать файлы csv, начиная с строки 4, для столбца New в этом фрейме данных значение будет одинаковым, если строки взяты из одних и тех же файлов csv. Мы можем рассматривать этот новый столбец как идентификатор CSV-файла.

Я обнаружил, что os.walk может помочь мне пройти по каталогу дерева, но как я могу просто прочитать два конкретных столбца в csv при создании нового столбца с соответствующим идентификатором?


person Ye Xu    schedule 11.07.2015    source источник
comment
Взгляните на numpy и csv.   -  person tomasyany    schedule 11.07.2015


Ответы (2)


Чтобы просмотреть каждый CSV-файл в корневом каталоге (включая вложенные папки), выполните итерацию по os.walk() и проверьте каждый файл на наличие расширения файла .csv, затем передайте путь к файлу и имя файла в process_file()

for root, dirs, files in os.walk(root_dir):
    for fi in files:
        if fi.split(".")[-1] == 'csv':
            process_file(root + fi)

Загрузите каждую строку CSV-файла в список, а затем разделите значения в каждой строке с помощью string.split().

На каждое значение теперь можно ссылаться по номеру строки и номеру столбца, например csv_file[row_num][col_num].

Чтобы обработать один файл, вы можете выполнить итерацию, используя любые значения для row_num и col_num, которые вы хотите:

def process_file(filename):
    title_line = 3 # indexing starts at 0, so one less than 4
    cols_to_keep = [0, 2, 3]

    # load entire CSV file into list (not good for massive files)
    f_lines = open(filename).readlines() 
    out_file = open("out.csv", "w")

    f_lines = [line.strip().split(",") for line in f_lines] # split each line in f_lines
    if os.stat("file").st_size == 0: # if file is empty, add title line
        out_file.write(",".join(f_lines[title_line]))
    for line in f_lines[title_line:]: # for each line after title line
        new_line = []
        for col_index in cols_to_keep:
           new_line.append(line[col_index])
        out_file.write(",".join(new_line))
person liamdiprose    schedule 11.07.2015
comment
Большое спасибо. Кажется, это решение предназначено для одного файла CSV. Как насчет чтения пакета CSV-файлов в нескольких папках в корневом каталоге? - person Ye Xu; 11.07.2015
comment
Желательно использовать модуль CSV, который знает, как обрабатывать экранирование и различные символы-разделители. - person Charlie Clark; 11.07.2015

Модуль csv предназначен именно для таких ситуаций. Возможно, вы захотите удалить первые три строки и использовать четвертую строку для получения заголовков, хотя, похоже, у вас все в порядке с позиционными индексами.

Затем вы сможете написать генератор для передачи во фрейм данных.

person Charlie Clark    schedule 11.07.2015