我有一个非常大的 csv 文件,无法完全加载到内存中。所以我想一块一块地读取它,将其转换为numpy数组,然后再做一些处理。
我已经检查过了:在Python中读取大文件的惰性方法? https://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python
但这里的问题是它是一个普通的阅读器,我无法在 csvReader 中找到任何指定大小的选项。
另外,因为我想将行转换为 numpy 数组,所以我不想将任何行读成两半,所以我不想指定大小,而是想要一些可以在阅读器中指定“行数”的东西。
是否有任何内置功能或简单的方法可以做到这一点。
The csv.reader https://docs.python.org/2/library/csv.html#csv.reader不会将整个文件读入内存。当您迭代文件时,它会逐行懒惰地迭代文件reader
目的。所以你可以只使用reader
像平常一样,但是break
无论您想阅读多少行,都可以从迭代中开始。您可以在用于实现的 C 代码reader object http://hg.python.org/cpython/file/7a1737033a23/Modules/_csv.c.
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)
calls next(file_object)
内部。因此,您将逐行迭代两者,而不将整个内容读入内存。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)