Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.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
使用numpy/pandas读取Python中CSV文件的最后N行_Python_Csv_Pandas_Numpy - Fatal编程技术网

使用numpy/pandas读取Python中CSV文件的最后N行

使用numpy/pandas读取Python中CSV文件的最后N行,python,csv,pandas,numpy,Python,Csv,Pandas,Numpy,是否有一种使用numpy或pandas快速读取Python中CSV文件最后N行的方法 我无法在numpy中执行skip_header操作,或者在pandas中执行skiprow操作,因为文件的长度不同,我始终需要最后N行 我知道我可以使用纯Python从文件的最后一行逐行读取,但这会非常慢。如果有必要的话,我可以这样做,但是使用numpy或pandas(本质上是使用C)的更有效的方法将非常有用 选项1 您可以使用numpy.genfromtxt读取整个文件,将其作为numpy数组获取,并获取最后

是否有一种使用
numpy
pandas
快速读取Python中CSV文件最后N行的方法

  • 我无法在
    numpy
    中执行
    skip_header
    操作,或者在
    pandas
    中执行
    skiprow
    操作,因为文件的长度不同,我始终需要最后N行

  • 我知道我可以使用纯Python从文件的最后一行逐行读取,但这会非常慢。如果有必要的话,我可以这样做,但是使用
    numpy
    pandas
    (本质上是使用C)的更有效的方法将非常有用


  • 选项1

    您可以使用
    numpy.genfromtxt
    读取整个文件,将其作为numpy数组获取,并获取最后N行:

    a = np.genfromtxt('filename', delimiter=',')
    lastN = a[-N:]
    
    选项2

    您可以通过通常的文件读取执行类似的操作:

    with open('filename') as f:
        lastN = list(f)[-N:]
    
    但这次您将得到最后N行的列表,作为字符串

    选项3-不将整个文件读取到内存中

    我们使用最多N个项目的列表来保存每个迭代的最后N行:

    lines = []
    N = 10
    with open('csv01.txt') as f:
        for line in f:
            lines.append(line)
            if len(lines) > 10:
                lines.pop(0)
    
    真正的csv需要一个小小的更改:

    import csv
    ...
    with ...
        for line in csv.reader(f):
        ...
    

    使用
    pandas
    read_csv()
    skiprows
    参数,更难的部分是查找csv中的行数。下面是一个可能的解决方案:

    with open('filename',"r") as f:
        reader = csv.reader(f,delimiter = ",")
        data = list(reader)
        row_count = len(data)
    
    df = pd.read_csv('filename', skiprows = row_count - N)
    

    对于一个10行的小测试文件,我尝试了两种方法——解析整个过程并选择最后N行,而不是加载所有行,但只解析最后N行:

    In [1025]: timeit np.genfromtxt('stack38704949.txt',delimiter=',')[-5:]
    1000 loops, best of 3: 741 µs per loop
    
    In [1026]: %%timeit 
          ...: with open('stack38704949.txt','rb') as f:
          ...:      lines = f.readlines()
          ...: np.genfromtxt(lines[-5:],delimiter=',')
    
    1000 loops, best of 3: 378 µs per loop
    
    这被标记为的副本。那里公认的答案是

    from collections import deque
    
    并收集了该结构中的最后N行。它还使用
    StringIO
    将行提供给解析器,这是一个不必要的复杂问题
    genfromtxt
    从任何给它行的东西中获取输入,所以行列表就可以了

    In [1031]: %%timeit 
          ...: with open('stack38704949.txt','rb') as f:
          ...:      lines = deque(f,5)
          ...: np.genfromtxt(lines,delimiter=',') 
    
    1000 loops, best of 3: 382 µs per loop
    
    基本上与
    readlines
    和slice的时间相同

    deque
    在文件非常大的情况下可能会有优势,并且挂起所有行的成本会很高。我认为这不会节省任何文件读取时间。还是要一行一行地读

    row\u count
    后接
    skip\u header
    方法的计时较慢;它需要读取文件两次<代码>跳过页眉仍需读取行

    In [1046]: %%timeit 
          ...: with open('stack38704949.txt',"r") as f:
          ...:       ...:     reader = csv.reader(f,delimiter = ",")
          ...:       ...:     data = list(reader)
          ...:       ...:     row_count = len(data)
          ...: np.genfromtxt('stack38704949.txt',skip_header=row_count-5,delimiter=',')
    
    The slowest run took 5.96 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000 loops, best of 3: 760 µs per loop
    
    为了计算行数,我们不需要使用
    csv.reader
    ,尽管它似乎不会花费太多额外的时间

    In [1048]: %%timeit 
          ...: with open('stack38704949.txt',"r") as f:
          ...:    lines=f.readlines()
          ...:    row_count = len(data)
          ...: np.genfromtxt('stack38704949.txt',skip_header=row_count-5,delimiter=',')
    
    1000 loops, best of 3: 736 µs per loop