【问题标题】:How can I read only the header column of a CSV file using Python?如何使用 Python 仅读取 CSV 文件的标题列?
【发布时间】:2014-09-17 17:33:59
【问题描述】:

我正在寻找一种方法来读取大量大型 CSV 文件的标题行。

使用 Pandas,我为每个 csv 文件提供了这种方法:

>>> df = pd.read_csv(PATH_TO_CSV)
>>> df.columns

我可以只用 csv 模块做到这一点:

>>> reader = csv.DictReader(open(PATH_TO_CSV))
>>> reader.fieldnames

这些问题是每个 CSV 文件的大小超过 500MB,读取每个文件的整个文件只是为了拉标题行似乎是一种巨大的浪费。

我所有这一切的最终目标是提取唯一的列名。一旦我拥有每个文件中的列标题列表,我就可以做到这一点。

如何快速只提取 CSV 文件的标题行?

【问题讨论】:

  • 请注意 DictReader 不会读取整个文件...因此您可以在所需文件上迭代地使用它并构建一个集合...我在答案中做了类似的事情我已经...

标签: python csv pandas


【解决方案1】:

这是一种方法。你得到 1 行。

In [9]: DataFrame(np.random.randn(10,4),columns=list('abcd')).to_csv('test.csv',mode='w')

In [10]: read_csv('test.csv',index_col=0,nrows=1)
Out[10]: 
          a         b         c         d
0  0.365453  0.633631 -1.917368 -1.996505

【讨论】:

  • 这确实读取了一个不必要的行,但为了阅读标题......但也许我并不完全清楚 OP 希望什么
  • 感谢您的回答,杰夫。我将您的答案与乔恩提供的答案进行了比较。两者都有效,但这个运行速度比他提供的慢约 5 倍。
  • @Jon Clements OP 只需要标题,但 read_csv() 不能与 nrows=0 一起运行 - read_csv() 需要至少读取一行。
  • @Andy 如果这对您来说很重要,那么请使用其他解决方案。这是熊猫方法。
  • @Jeff & Jon Clements:我认为您可以添加 header=None 以将标题作为正常行 - 没有第一行数据。
【解决方案2】:

我以iglob 为例搜索.csv 文件,但一种方法是使用集合,然后根据需要进行调整,例如:

import csv
from glob import iglob

unique_headers = set()
for filename in iglob('*.csv'):
    with open(filename, 'rb') as fin:
        csvin = csv.reader(fin)
        unique_headers.update(next(csvin, []))

【讨论】:

  • 我将此与 Jeff 提供的答案进行了比较。对于我的数据集样本,这个运行速度比 pandas 答案快约 5 倍。我怀疑这是因为它没有读取额外的数据行(我也很欣赏有关 DictReader 的说明)。谢谢
  • @Andy 我怀疑真正的区别并不是不必要地读取额外的行,而是创建 DataFrame 的更多开销......
  • 请问这句话是什么意思? “unique_headers.update(next(csvin, []))”@JonClements
【解决方案3】:

我参加聚会可能有点晚了,但这是仅使用 Python 标准库的一种方法。在处理文本数据时,我更喜欢使用 Python 3,因为 unicode。所以这非常接近你原来的建议,除了我只阅读一行而不是整个文件。

import csv    

with open(fpath, 'r') as infile:
    reader = csv.DictReader(infile)
    fieldnames = reader.fieldnames

希望对您有所帮助!

【讨论】:

  • 这应该是新接受的答案。这是最快最清晰的方法
【解决方案4】:

怎么样:

pandas.read_csv(PATH_TO_CSV, nrows=1).columns

这将只读取第一行并返回找到的列。

【讨论】:

    【解决方案5】:

    这取决于标头的用途,如果您需要标头仅用于比较目的(我的情况),此代码将简单且超快速,它将整个标头作为一个字符串读取。您可以根据需要将所有收集的字符串一起转换:

    for filename in glob.glob(files_path+"\*.csv"):
        with open(filename) as f:
            first_line = f.readline()
    

    【讨论】:

      【解决方案6】:

      扩展answer given by Jeff 现在可以使用pandas 而无需实际读取任何行。

      In [1]: import pandas as pd
      In [2]: import numpy as np
      In [3]: pd.DataFrame(np.random.randn(10, 4), columns=list('abcd')).to_csv('test.csv', mode='w')
      
      In [4]: pd.read_csv('test.csv', index_col=0, nrows=0).columns.tolist()
      Out[4]: ['a', 'b', 'c', 'd']
      

      pandas 的优势在于它可以更优雅地处理 CSV 编码。

      【讨论】:

      • 嗨,很棒的小费。我发现用header 替换index_col 让我得到了一个我缺少的额外字段名称。否则,其余的工作完美!
      • @MarkMoretto 我认为这取决于您的 CSV 中是否有一个没有标题的额外索引列。如果不是,那么将index_col=False 设置为header=0 可能是最清楚的。
      【解决方案7】:
      import pandas as pd
      
      get_col = list(pd.read_csv("first_test_pipe.csv",sep="|",nrows=1).columns)
      print(get_col)
      

      【讨论】:

        【解决方案8】:

        你错过了 nrows=1 参数到 read_csv

        >>> df= pd.read_csv(PATH_TO_CSV, nrows=1)
        >>> df.columns
        

        【讨论】:

          【解决方案9】:

          你可以很容易地使用这个:

          df = pd.read_csv("path.csv", skiprows=0, nrows=2)
          df.columns.to_list()
          

          在这种情况下,您只能阅读很少的行来获取标题

          【讨论】:

            【解决方案10】:

            如果您只对标头感兴趣并且想使用 pandas,那么除了 csv 文件名之外,您需要传递的唯一额外内容是“nrows=0”:

            headers = pd.read_csv("test.csv", nrows=0)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-10-25
              • 1970-01-01
              • 2010-12-08
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多