Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:在文件中检索逗号分隔数据的最快方法_Python - Fatal编程技术网

Python:在文件中检索逗号分隔数据的最快方法

Python:在文件中检索逗号分隔数据的最快方法,python,Python,我有一个二十万行的文件,看起来像这样: 01,T,None,Red,Big 02,F,None,Purple,Small 03,T,None,Blue,Big ....... 我想要从整个文件中检索第n列的内容。例如,第4列将是: Red Purple Blue 由于文件很大,我想知道最有效的方法 显而易见的解决方案是逐行检查文件,然后应用split(“,”)并获取数组中的第四项,但我想知道是否有更好的方法。我认为您不能仅仅阅读文件并使用str.split()。但是,您尚未向我们显示所有代码

我有一个二十万行的文件,看起来像这样:

01,T,None,Red,Big
02,F,None,Purple,Small
03,T,None,Blue,Big
.......
我想要从整个文件中检索第n列的内容。例如,第4列将是:

Red
Purple
Blue
由于文件很大,我想知道最有效的方法


显而易见的解决方案是逐行检查文件,然后应用split(“,”)并获取数组中的第四项,但我想知道是否有更好的方法。

我认为您不能仅仅阅读文件并使用
str.split()
。但是,您尚未向我们显示所有代码。。。在处理整个文件之前,您可能希望确保没有将其读入内存(使用
file.readlines()
方法函数或
file.read()

像这样的事情可能是你能做的最好的事情:

with open(filename, "rt") as f:
    for line in f:
        x = line.split(',')[3]
        # do something with x
如果您希望能够将输入文件视为只包含一列,我建议将上述内容包装到一个函数中,该函数使用
yield
来提供值

def get_col3(f):
    for line in f:
        yield line.split(',')[3]

with open(filename, "rt") as f:
    for x in get_col3(f):
        # do something with x
考虑到文件I/O是Python C核心的一部分,您可能无法通过使用技巧来获得太多额外的速度。但是您可以尝试编写一个简单的C程序来读取文件,找到第四列,并将其打印到标准输出,然后将其导入Python程序

如果您经常使用同一个输入文件,那么将其保存为某种二进制文件格式可能会比解析文本文件更快。我相信那些处理像HDF5这样的大数据集的科学家,Python通过Pandas对此有很好的支持

嗯,现在我想起来了:你应该试着用熊猫来导入文本文件。我记得《熊猫》的作者说他写了一些低级代码,大大加快了解析输入文件的速度

哦,找到了:

嗯。在Pandas文档中,您可以使用
read_csv()
和可选参数
usecols
来指定所需列的子集,它将丢弃所有其他内容

我认为Pandas可能以速度取胜的原因是:当您调用
line.split(',')
时,Python将为每个列构建一个string对象,并为您构建一个列表。然后对列表进行索引以获取所需的一个字符串,Python将销毁该列表并销毁它创建的对象(您想要的列除外)。Python对象池中的这种“搅动”需要一些时间,您可以将该时间乘以文件中的行数。Pandas可以解析这些行,并且只返回Python您需要的行,因此它可能会赢


但所有这些都只是猜测。加快速度的规则是:量度。运行代码,测量它的速度,然后运行其他代码并测量,看看加速是否值得。

我认为您建议的方法是最好的方法:

def nth_column(filepath, n):
    n -= 1 # since indices starts at 0
    columns = []
    with open(filepath, 'r') as my_file:
        for line in my_file:
            try: columns.append(line.split(',')[n])
            except IndexError: pass # if the line doesn't have n columns
    return columns
这是读取csv文件的正确方法。生成器可以帮助您在大文件的速度和内存使用之间取得适当的平衡

from csv import reader
def getNthCol(filename, n):
  with open(filename) as afile:
    r = reader(afile)
    for line in r:
      yield r[n]
如果列号的偏移量为1,则可能需要将n调整为-1

更新 另一种几乎肯定是渐进效率较低,但实际上可能相当快的方法是转置文件并获取某一行

def getNthCol(filename, n):
  with open(filename) as afile:
    return zip(*reader(afile))[n]

我只是简单地打开它,然后用f中的行进行检查,所以我认为这是正确的,不是吗?是的。当你打开一个文件时,你会得到一个
文件
对象,当你迭代
文件
对象时,你会一次得到一行。但是你可以做一些事情来抓取文件的所有内容:
f.readlines()
f.read()
list(f)
[line for line in f]
,等等+1尽管我对你早期的陈述不太确定,你可能希望确保你没有将整个文件读入内存。事实上,这可能正是医生的要求。在整个文件中都有阅读的方法,而且有很多这样的先例让提问者高估了这样做的实际内存占用。@kojiro,我相信cgf的话,这个文件“非常大”。如果一个文件足够大,以至于读取整个文件会导致交换,那么这可能是一个巨大的速度损失。另外,我不认为仅仅为了提取一列而将整个文件拖入更好;保存您需要的数据,而不是保存所有数据,保存您需要的部分,然后释放不需要的数据,这是再慢不过的了。另外,我看了你的链接,我不明白你想通过链接来表达什么意思。csv模块的另一个优点是:它是在CI中实现的。我知道它看起来像是在谈论csv文件,但我在这篇文章中尽可能简化了问题。文件的实际布局。我只是在尝试优化似乎最慢的位。尽管如此,回答还是不错。@cgf除非你想进一步澄清这个问题,否则你仍然很清楚你想要CSV。另外,可以肯定的是,它被称为CSV,但它可以处理许多不同类型的分隔文件,不仅仅是逗号。你说这个文件非常大,但与你实际拥有的内存相比,它有多大,当你说高效时,你是指速度还是存储?接近100万行,我对速度感兴趣。如果该文件具有代表性,它有100万行,那么它大约有2000万行。除非您使用的是非常有限的机器,否则您可以留出20米的时间进行一次突发,以便读取整个文件并获得所需的列。我一直认为将文件读入内存将是一个非常糟糕的主意,但我也会尝试您的方法,看看会发生什么。谢谢你的提示。