在python中读取大csv文件的行
我有一个非常大的csv文件,我不能完全加载到内存中。所以我想一块一块地读,把它转换成numpy数组,然后做更多的处理 我已经检查过: 但这里的问题是,它是一个普通的读取器,我无法在csvReader中找到任何指定大小的选项 另外,因为我想将行转换为numpy数组,所以我不想将任何行对半读取,所以我不想指定大小,而是想在reader中指定“行数” 是否有任何内置函数或简单方法来执行此操作。不会将整个文件读入内存。当您迭代在python中读取大csv文件的行,python,csv,file-io,generator,Python,Csv,File Io,Generator,我有一个非常大的csv文件,我不能完全加载到内存中。所以我想一块一块地读,把它转换成numpy数组,然后做更多的处理 我已经检查过: 但这里的问题是,它是一个普通的读取器,我无法在csvReader中找到任何指定大小的选项 另外,因为我想将行转换为numpy数组,所以我不想将任何行对半读取,所以我不想指定大小,而是想在reader中指定“行数” 是否有任何内置函数或简单方法来执行此操作。不会将整个文件读入内存。当您迭代读取器对象时,它会一行一行地懒洋洋地迭代文件。因此,您可以像平常一样使用读取
读取器
对象时,它会一行一行地懒洋洋地迭代文件。因此,您可以像平常一样使用读取器
,但是在您阅读了多少行您想阅读的内容后,从迭代中中断
。你可以在地图上看到这一点
读取器对象的初始值设定项:
静态PyObject*
csv_读取器(PyObject*模块、PyObject*参数、PyObject*关键字_参数)
{
PyObject*迭代器,*方言=NULL;
ReaderObj*self=PyObject\u GC\u New(ReaderObj,&Reader\u类型);
如果(!self)
返回NULL;
self->方言=NULL;
self->fields=NULL;
self->input\u iter=NULL;
self->field=NULL;
//我们不在乎的东西
// ...
self->input\u iter=PyObject\u GetIter(迭代器);//这里我们保存传入的迭代器(文件对象)
if(self->input\u iter==NULL){
PyErr_设置字符串(PyExc_类型错误,
“参数1必须是迭代器”);
Py_DECREF(self);
返回NULL;
}
静态PyObject*
Reader_iternext(ReaderObj*self)//这是在调用'next(Reader_obj)``时调用的内容(这是for循环在内部执行的操作)
{
PyObject*字段=NULL;
Py_-UCS4 c;
管道位置;
无符号整数类;
作废*数据;
PyObject*lineobj;
如果(解析_重置(自)<0)
返回NULL;
做{
lineobj=PyIter\u-Next(self->input\u-iter);//相当于调用'Next(input\u-iter)`
if(lineobj==NULL){
/*输入或异常结束*/
如果(!PyErr_occurrent()&&(self->field_len!=0||
self->state==在\u引用的\u字段中){
如果(自我->方言->严格)
PyErr_SetString(_csvstate_global->error_obj,
“数据意外终止”);
else if(解析保存字段(self)>=0)
打破
}
返回NULL;
}
如您所见,next(reader\u object)
在内部调用next(file\u object)
。因此您逐行迭代这两个对象,而没有将整个内容读入内存。我使用了这个函数。
其基本思想是制作一个生成器来生成文件中的数字
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
def iter\u loadtxt(文件名,分隔符=',,skiprows=0,read\u range=None,dtype=float):
'''
逐行读取文件并将其转换为Numpy数组。
:param分隔符:字符
:param skiprows:int
:param read_range:[int,int]或None。将其设置为None,函数将读取整个文件。
:param dtype:type
'''
def iter_func():
打开(文件名为“r”)作为填充:
对于范围内的uu(skiprows):
下一步(填充)
如果读取范围为“无”:
对于填充中的线:
line=line.rstrip().split(分隔符)
对于第行中的项目:
产量数据类型(项目)
其他:
计数器=0
对于填充中的线:
如果计数器<读取范围[0]:
计数器+=1
其他:
计数器+=1
对于第行中的项目:
产量数据类型(项目)
如果计数器>=读取范围[1]:
打破
iter_loadtxt.rowlength=len(行)
data=np.fromiter(iter_func(),dtype=dtype)
data=data.reformate((-1,iter_loadtxt.rowlength))
返回数据
您研究过了吗?我自己没有使用Pandas,但我认为它对这类事情很有用。除了在用于创建读取器的file对象上设置buffering
参数之外,还有其他方法吗?所有Python对象都支持延迟求值,无需进一步努力,您只需确保该文件不会尝试进行延迟求值将整个内容拉入内存。