【问题标题】:reading rows of big csv file in python在python中读取大csv文件的行
【发布时间】:2014-07-21 15:26:10
【问题描述】:

我有一个非常大的 csv 文件,我无法将其全部加载到内存中。所以我想一块一块地读,把它转换成numpy数组,然后再做一些处理。

我已经检查过: Lazy Method for Reading Big File in Python?

但这里的问题是它是一个普通的阅读器,我无法在 csvReader 中找到任何指定大小的选项。

此外,由于我想将行转换为 numpy 数组,我不想将任何行读取一半,因此我想要在阅读器中指定“行数”的东西,而不是指定大小。

有没有内置的功能或者简单的方法。

【问题讨论】:

  • 您查看过pandas.pydata.org 吗?我自己没有使用过 Pandas,但我认为它对这类事情很有用。
  • 除了在您用来创建阅读器的文件对象上设置buffering 参数之外,还有更多内容吗?所有 Python 对象都支持惰性求值,无需进一步努力,您只需确保文件不会尝试将整个内容拉入内存。

标签: python csv file-io generator


【解决方案1】:

csv.reader 不会将整个文件读入内存。当您遍历 reader 对象时,它会逐行懒惰地遍历文件。所以你可以像往常一样使用reader,但是在你阅读了你想阅读的许多行之后,你可以从迭代中使用break。您可以在C-code used to implement the reader object 中看到这一点。

Initializer for the reader objecT:
static PyObject *
csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
{
    PyObject * iterator, * dialect = NULL;
    ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);

    if (!self)
        return NULL;

    self->dialect = NULL;
    self->fields = NULL;
    self->input_iter = NULL;
    self->field = NULL;
    // stuff we dont care about here
    // ...
    self->input_iter = PyObject_GetIter(iterator);  // here we save the iterator (file object) we passed in
    if (self->input_iter == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "argument 1 must be an iterator");
        Py_DECREF(self);
        return NULL;
    }

static PyObject *
Reader_iternext(ReaderObj *self)  // This is what gets called when you call `next(reader_obj)` (which is what a for loop does internally)
{
    PyObject *fields = NULL;
    Py_UCS4 c;
    Py_ssize_t pos, linelen;
    unsigned int kind;
    void *data;
    PyObject *lineobj;

    if (parse_reset(self) < 0)
        return NULL;
    do {
        lineobj = PyIter_Next(self->input_iter);  // Equivalent to calling `next(input_iter)`
        if (lineobj == NULL) {
            /* End of input OR exception */
            if (!PyErr_Occurred() && (self->field_len != 0 ||
                                      self->state == IN_QUOTED_FIELD)) {
                if (self->dialect->strict)
                    PyErr_SetString(_csvstate_global->error_obj,
                                    "unexpected end of data");
                else if (parse_save_field(self) >= 0)
                    break;
            }
            return NULL;
        }

如您所见,next(reader_object) 在内部调用next(file_object)。因此,您将逐行迭代,而无需将整个内容读入内存。

【讨论】:

    【解决方案2】:

    我使用了这个功能。 基本思想是制作一个生成器来生成文件中的数字。

    def iter_loadtxt(filename, delimiter=',', skiprows=0, read_range=None, dtype=float):
        '''
        Read the file line by line and convert it to Numpy array.
        :param delimiter: character
        :param skiprows : int
        :param read_range: [int, int] or None. set it to None and the function will read the whole file.
        :param dtype: type
        '''
        def iter_func():
            with open(filename, 'r') as infile:
                for _ in range(skiprows):
                    next(infile)
                if read_range is None:
                    for line in infile:
                        line = line.rstrip().split(delimiter)
                        for item in line:
                            yield dtype(item)
                else:
                    counter = 0
                    for line in infile:
                        if counter < read_range[0]:
                            counter += 1
                        else:
                            counter += 1
                            for item in line:
                                yield dtype(item)
    
                        if counter >= read_range[1]:
                            break
    
            iter_loadtxt.rowlength = len(line)
    
        data = np.fromiter(iter_func(), dtype=dtype)
        data = data.reshape((-1, iter_loadtxt.rowlength))
        return data
    

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 2017-08-11
      • 2018-03-11
      • 2012-11-05
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 2021-09-02
      • 2020-08-20
      相关资源
      最近更新 更多