Как предварительно обработать данные перед pandas.read_csv () - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть слегка поврежденный CSV-файл, который я хочу предварительно обработать перед чтением с помощью pandas.read_csv (), т. Е. Выполнить поиск / замену в нем.

Я попытался открыть файл и выполнить предварительную обработку в генераторе, который я затем передал read_csv ():

    def in_stream():
    with open("some.csv") as csvfile:
        for line in csvfile:
            l = re.sub(r'","',r',',line)
            yield l

    df = pd.read_csv(in_stream())

К сожалению, это просто бросает

ValueError: Invalid file path or buffer object type: <class 'generator'>

Хотя, глядя на источник Panda, я ожидал, что он сможет работать с итераторами, то есть с генераторами.

Я нашел только эту [статью] ( Использование пользовательского объекта в pandas.read_csv () ), в которой рассказывается, как обернуть генератор в объект, похожий на файл, но, похоже, он работает только с файлами в байтовом режиме.

Итак, в конце я ищу шаблон для построения конвейера, который открывает файл, читает его построчно, разрешает предварительную обработку и затем передает его, например, в файл. pandas.read_csv ().

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

После дальнейшего изучения источника Pandas стало очевидно, что он не просто требует итерации, но также хочет, чтобы это был файл, выраженный наличием метода чтения (is_file_like () в inference.py).

Итак, я построил генератор по-старому

class InFile(object):
def __init__(self, infile):
    self.infile = open(infile)

def __next__(self):
    return self.next()

def __iter__(self):
    return self

def read(self, *args, **kwargs):
    return self.__next__()

def next(self):
    try:
        line: str = self.infile.readline()
        line = re.sub(r'","',r',',line) # do some fixing
        return line
    except:
        self.infile.close()
        raise StopIteration

Это работает в pandas.read_csv ():

df = pd.read_csv(InFile("some.csv"))

Для меня это выглядит очень сложно, и мне интересно, есть ли лучшее (→ более элегантное) решение.

0 голосов
/ 03 сентября 2018

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

import re
from io import StringIO
import pandas as pd

with open('file.csv') as file:
    lines = [re.sub(r'","', r',', line) for line in file]

df = pd.read_csv(StringIO('\n'.join(lines)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...