【问题标题】:How to pre-process data before pandas.read_csv()如何在 pandas.read_csv() 之前预处理数据
【发布时间】:2019-02-08 17:26:59
【问题描述】:

我有一个稍微损坏的 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 的源代码时,我希望它能够在迭代器上工作,从而在生成器上工作。

我只找到了这篇 [文章] (Using a custom object in pandas.read_csv()),概述了如何将生成器包装到类似文件的对象中,但它似乎只适用于字节模式的文件。

所以最后我正在寻找一种模式来构建一个打开文件的管道,逐行读取它,允许预处理,然后将其馈送到例如pandas.read_csv()。

【问题讨论】:

  • 你试过了吗...df = pd.DataFrame(in_stream())
  • 我认为您需要在 in_stream() 末尾添加 return l
  • @JonClements 我认为构造函数不适用于迭代器。
  • @JonClements 这确实会消耗来自生成器的输入,但不会像 read_csv() 那样解析字段。

标签: python-3.x pandas


【解决方案1】:

在对 Pandas 的源代码进行进一步调查后,很明显,它不仅需要一个可迭代对象,而且还希望它是一个文件,通过具有读取方法(inference.py 中的 is_file_like() )来表达。

所以,我用旧的方式构建了一个生成器

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"))

在我看来,这看起来超级复杂,我想知道是否有更好(→ 更优雅)的解决方案。

【讨论】:

    【解决方案2】:

    这是一个适用于较小 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)))
    

    【讨论】:

    • 感谢您的建议。唉,我也在寻找一种适用于大文件的方法。这个想法是能够构建一个完整的处理管道,将数据从源通过多个处理器流式传输到最终目的地。
    猜你喜欢
    • 2018-09-09
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2013-09-01
    • 2021-01-28
    • 1970-01-01
    • 2019-07-19
    相关资源
    最近更新 更多