Извлечение данных из определенных столбцов файлов CSV в Python - PullRequest
0 голосов
/ 18 июня 2019

Мне нужна быстрая помощь по чтению CSV-файлов с использованием Python и сохранению его в файле типа данных, чтобы использовать данные для построения графика после хранения всех данных в разных файлах.

Я искал его, но во всех обнаруженных случаях в данных были заголовки.Мои данные не являются частью заголовка.Они разделены табуляцией.И мне нужно хранить только конкретные столбцы данных.Пример:

12345601 2345678@abcdef 1 2 365 places

В этом случае, например, я хотел бы сохранить только «2345678 @ abcdef» и «365» в новом файле Python, чтобы использовать егов будущем создать график.

Кроме того, у меня есть более 1 CSV-файла в папке, и мне нужно сделать это в каждом из них.Источники, которые я нашел, не говорили об этом и упоминали только:

# open csv file
with open(csv_file, 'rb') as csvfile:

Может ли кто-нибудь отослать меня на уже отвеченный вопрос или помочь мне с этим?

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Вот еще один подход, использующий именованный кортеж, который поможет извлечь выбранные поля из файла CSV, а затем позволит вам записать их в новый файл CSV.

from collections import namedtuple    
import csv

# Setup named tuple to receive csv data
# p1 to p5 are arbitrary field names associated with the csv file
SomeData = namedtuple('SomeData', 'p1, p2, p3, p4, p5, p6')

# Read data from the csv file and create a generator object to hold a reference to the data
# We use a generator object rather than a list to reduce the amount of memory our program will use
# The captured data will only have data from the 2nd & 5th column from the csv file
datagen = ((d.p2, d.p5) for d in map(SomeData._make, csv.reader(open("mydata.csv", "r"))))

# Write the data to a new csv file
with open("newdata.csv","w", newline='') as csvfile:
    cvswriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    # Use the generator created earlier to access the filtered data and write it out to a new csv file
    for d in datagen:
        cvswriter.writerow(d)

Исходные данные в "mydata.csv":

12345601,2345678@abcdef,1,2,365,places  
4567,876@def,0,5,200,noplaces

Выходные данные в "newdata.csv":

2345678@abcdef,365  
876@def,200

РЕДАКТИРОВАТЬ 1: Для данных с разделителями табуляции внесите следующие изменения в код:
изменить
datagen = ((d.p2, d.p5) for d in map(SomeData._make, csv.reader(open("mydata.csv", "r"))))
до
datagen = ((d.p2, d.p5) for d in map(SomeData._make, csv.reader(open("mydata2.csv", "r"), delimiter='\t', quotechar='"')))
и
cvswriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
до
cvswriter = csv.writer(csvfile, delimiter='\t', quotechar='"', quoting=csv.QUOTE_MINIMAL)

1 голос
/ 18 июня 2019

. , , и сохраняя его в PY-файле, чтобы использовать данные для построения графика после сохранения всех данных в разных файлах. , .

. , , Я хотел бы хранить только "2345678 @ abcdef" и "365" в новом файле Python. , .

Вы уверены, что хотите сохранить данные в файле Python? Предполагается, что файлы Python содержат код Python, и они должны быть исполняемыми интерпретатором Python. Было бы лучше сохранить ваши данные в файле типа данных (скажем, preprocessed_data.csv).

Чтобы получить список файлов, соответствующих шаблону, вы можете использовать встроенную в Python glob библиотеку .

Вот пример того, как вы можете прочитать несколько CSV-файлов в каталоге и извлечь нужные столбцы из каждого:

import glob

# indices of columns you want to preserve
desired_columns = [1, 4]
# change this to the directory that holds your data files
csv_directory = '/path/to/csv/files/*.csv'

# iterate over files holding data
extracted_data = []
for file_name in glob.glob(csv_directory):
    with open(file_name, 'r') as data_file:
        while True:
            line = data_file.readline()
            # stop at the end of the file
            if len(line) == 0:
                break

            # splits the line by whitespace
            tokens = line.split()
            # only grab the columns we care about
            desired_data = [tokens[i] for i in desired_columns]
            extracted_data.append(desired_data)

Было бы легко записать извлеченные данные в новый файл. В следующем примере показано, как можно сохранить данные в CSV-файле.

output_string = ''
for row in extracted_data:
    output_string += ','.join(row) + '\n'

with open('./preprocessed_data.csv', 'w') as csv_file:
    csv_file.write(output_string)

Edit:

Если вы не хотите объединять все CSV-файлы, вот версия, которая может обрабатывать по одному:

def process_file(input_path, output_path, selected_columns):
    extracted_data = []    
    with open(input_path, 'r') as in_file:
        while True:
            line = in_file.readline()
            if len(line) == 0: break
            tokens = line.split()
            extracted_data.append([tokens[i] for i in selected_columns])

    output_string = ''
    for row in extracted_data:
        output_string += ','.join(row) + '\n'

    with open(output_path, 'w') as out_file:
        out_file.write(output_string)

# whenever you need to process a file:
process_file(
    '/path/to/input.csv', 
    '/path/to/processed/output.csv',
    [1, 4])

# if you want to process every file in a directory:
target_directory = '/path/to/my/files/*.csv'
for file in glob.glob(target_directory):
    process_file(file, file + '.out', [1, 4])

Редактировать 2:

Следующий пример обработает каждый файл в каталоге и запишет результаты в выходной файл с аналогичным именем в другом каталоге:

import os
import glob

input_directory = '/path/to/my/files/*.csv'
output_directory = '/path/to/output'
for file in glob.glob(input_directory):
    file_name = os.path.basename(file) + '.out'
    out_file = os.path.join(output_directory, file_name)
    process_file(file, out_file, [1, 4])

Если вы хотите добавить заголовки к выводу, тогда process_file можно изменить следующим образом:

def process_file(input_path, output_path, selected_columns, column_headers=[]):
    extracted_data = []    
    with open(input_path, 'r') as in_file:
        while True:
            line = in_file.readline()
            if len(line) == 0: break
            tokens = line.split()
            extracted_data.append([tokens[i] for i in selected_columns])

    output_string = ','.join(column_headers) + '\n'
    for row in extracted_data:
        output_string += ','.join(row) + '\n'

    with open(output_path, 'w') as out_file:
        out_file.write(output_string)
...