【问题标题】:How to find the number of columns in a tab separated file如何查找制表符分隔文件中的列数
【发布时间】:2015-07-07 11:05:59
【问题描述】:

我有一个制表符分隔的文件,其中包含 10 亿行(想象一下 200 多列而不是 3 列):

abc -0.123  0.6524  0.325
foo -0.9808 0.874   -0.2341 
bar 0.23123 -0.123124   -0.1232

如果列数未知,如何查找制表符分隔文件中的列数?

我试过了:

import io
with io.open('bigfile', 'r') as fin:
    num_columns = len(fin.readline().split('\t'))

并且(来自@EdChum,Read a tab separated file with first column as key and the rest as values):

import pandas as pd
num_columns = pd.read_csv('bigfile', sep='\s+', nrows=1).shape[1]  

我还能如何获得列数?哪种方式最有效?(想象一下,我突然收到一个列数未知的文件,比如超过 100 万列)

【问题讨论】:

  • 最后一个 sn-p(我编写的)有什么问题,它只读取一行并吐出一个数字?
  • 或者一般来说,读取文件的第一行并计算列数有什么问题?
  • @EdChum,我只是想看看是否有其他方法可以获取列数,然后进行基准测试。
  • 好吧,如果它是最快的,请告诉我,我很想知道 pandas 是如何堆叠起来的
  • 我尝试计时不同的代码,但熊猫给了我一个StopIteration: 错误

标签: python calculated-columns csv


【解决方案1】:

有一个str.count()方法:

h = file.open('path', 'r')
columns = h.readline().count('\t') + 1
h.close()

【讨论】:

    【解决方案2】:

    一个有 100000 列的文件的一些计时,count 似乎最快,但相差 1:

    In [14]: %%timeit                    
    with open("test.csv" ) as f:
        r = csv.reader(f, delimiter="\t")
        len(next(r))
       ....: 
    10 loops, best of 3: 88.7 ms per loop
    
    In [15]: %%timeit                    
    with open("test.csv" ) as f:
        next(f).count("\t")
       ....: 
    100 loops, best of 3: 11.9 ms per loop
    with io.open('test.csv', 'r') as fin:
        num_columns = len(next(fin).split('\t'))
        ....: 
     10 loops, best of 3: 133 ms per loop
    

    实际上使用 str.translate 似乎是最快的,尽管您需要再次添加 1:

    In [5]: %%timeit
    with open("test.csv" ) as f:
        n = next(f)
        (len(n) - len(n.translate(None, "\t")))
       ...: 
    100 loops, best of 3: 9.9 ms per loop
    

    pandas 解决方案给我一个错误:

    in pandas.parser.TextReader._read_low_memory (pandas/parser.c:7977)()
    
    StopIteration: 
    

    使用 readline 会增加更多开销:

    In [19]: %%timeit
    with open("test.csv" ) as f:
        f.readline().count("\t")
       ....: 
    10 loops, best of 3: 28.9 ms per loop
    In [30]: %%timeit
    with io.open('test.csv', 'r') as fin:
        num_columns = len(fin.readline().split('\t'))
       ....: 
    10 loops, best of 3: 136 ms per loop
    

    使用 python 3.4 的不同结果:

    In [7]: %%timeit
    with io.open('test.csv', 'r') as fin:
        num_columns = len(next(fin).split('\t'))
       ...: 
    10 loops, best of 3: 102 ms per loop
    
    In [8]: %%timeit
    with open("test.csv" ) as f:
        f.readline().count("\t")
       ...: 
    
    100 loops, best of 3: 12.7 ms per loop   
    In [9]:     
    In [9]: %%timeit
    with open("test.csv" ) as f:
        next(f).count("\t")
       ...: 
    100 loops, best of 3: 11.5 ms per loop    
    In [10]: %%timeit
    with io.open('test.csv', 'r') as fin:
        num_columns = len(next(fin).split('\t'))
       ....: 
    10 loops, best of 3: 89.9 ms per loop    
    In [11]: %%timeit
    with io.open('test.csv', 'r') as fin:
        num_columns = len(fin.readline().split('\t'))
       ....: 
    10 loops, best of 3: 92.4 ms per loop   
    In [13]: %%timeit     
    with open("test.csv" ) as f:
        r = csv.reader(f, delimiter="\t")
        len(next(r))
       ....: 
    10 loops, best of 3: 176 ms per loop
    

    【讨论】:

    • @alvas,添加区别,我会在几分钟内添加更多不同的方法
    • 你的熊猫解决方案是什么?
    • 啊好吧,如果你明确设置low_memory=False会发生什么?
    • 好的,50.6 秒后完成
    • 呃,太糟糕了!你用的是什么版本的 pandas、numpy 和 python?
    猜你喜欢
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 2023-04-07
    • 2017-02-12
    • 2021-09-28
    • 2012-04-26
    相关资源
    最近更新 更多