【问题标题】:How to check if a CSV has a header using Python?如何使用 Python 检查 CSV 是否有标题?
【发布时间】:2017-03-04 18:04:47
【问题描述】:

我有一个 CSV 文件,我想检查第一行是否只有字符串(即标题)。我试图避免使用任何额外的东西,比如 pandas 等。我想我会使用 if 语句,比如 if row[0] is a string print this is a CSV,但我真的不知道该怎么做: -S 有什么建议吗?

【问题讨论】:

标签: python python-2.7 csv


【解决方案1】:

简单地使用 try 和 except ::::::::::::::::::::::::::

import pandas as pd
try:
   data = pd.read_csv('file.csv',encoding='ISO-8859-1')
   print('csv file has header::::::')        
except:
    print('csv file has no header::::::')
   

【讨论】:

    【解决方案2】:

    对于不一定是 '.csv' 格式的文件,这非常有用:

    built-in function in Python to check Header in a Text file

        def check_header(filename):
            with open(filename) as f:
                first = f.read(1)
            return first not in '.-0123456789'
    

    回答者:https://stackoverflow.com/users/908494/abarnert

    发帖链接:https://stackoverflow.com/a/15671103/7763184

    【讨论】:

      【解决方案3】:

      我认为检查这一点的最佳方法是 -> 只需从文件中读取第一行,然后匹配您的字符串而不是任何库。

      【讨论】:

        【解决方案4】:

        好吧,我遇到了完全相同的问题,因为 sniffer.has_header 的 has_header 返回错误,甚至还做了一个非常简单的检查器,适用于我的情况

            has_header = ''.join(next(some_csv_reader)).isalpha()
        

        我知道它并不完美,但它似乎正在工作......为什么不只是一个简单的替换并检查结果是否为 alpha ......然后我把它放在我的 def 和它失败了...... :(然后我看到了“光”
        问题不在于 has_header 问题在于我的代码,因为我还想在解析实际的 .csv 之前检查分隔符......但是所有的嗅探在推进时都有“成本”在 csv 中一次一行。 !!!
        因此,为了让 has_header 正常工作,您应该确保在使用它之前已重置所有内容。 就我而言,我的方法是:

          def _get_data(self, filename):
                sniffer = csv.Sniffer()
                training_data = ''
                with open(filename, 'rt') as csvfile:
                    dialect = csv.Sniffer().sniff(csvfile.read(2048))
                    training_data = csv.reader(csvfile, delimiter=dialect.delimiter)
                    csvfile.seek(0)
                    has_header=csv.Sniffer().has_header(csvfile.read(2048))
                    #has_header = ''.join(next(training_data)).isalpha()
                    csvfile.seek(0)
        

        【讨论】:

          【解决方案5】:

          这是我在 pandas 中使用的一个函数,用于分析 header 应该设置为 'infer' 还是 None

          def identify_header(path, n=5, th=0.9):
              df1 = pd.read_csv(path, header='infer', nrows=n)
              df2 = pd.read_csv(path, header=None, nrows=n)
              sim = (df1.dtypes.values == df2.dtypes.values).mean()
              return 'infer' if sim < th else None
          

          基于一个小样本,该函数检查具有和不具有标题行的 dtypes 的相似性。如果 dtypes 匹配特定百分比的列,则假定不存在标题。我发现0.9 的阈值适用于我的用例。这个函数也相当快,因为​​它只读取 csv 文件的一小部分样本。

          【讨论】:

          • 如果 csv 文件很大。这可能是个问题
          • @FoggyMindedGreenhorn 为什么?我们不会在这里阅读整个文件。
          【解决方案6】:

          Python 有一个内置的 CSV module 可以提供帮助。例如

          import csv
          with open('example.csv', 'rb') as csvfile:
              sniffer = csv.Sniffer()
              has_header = sniffer.has_header(csvfile.read(2048))
              csvfile.seek(0)
              # ...
          

          【讨论】:

          • 谢谢。它对我来说效果很好。但是你能解释一下为什么你通过2048而不是任何其他号码吗?
          • @AzharKhan 2048 是一个完全任意的数字。它只需要足够大以读取至少两到三行 CSV 行。您可以改为读取几行字符串并将其传递给has_header
          • 感谢您的解释
          • sniffer.has_header 总是返回 True... 我测试了几个 csv 文件... :/
          • 它可以工作,但是对于一个大文件,它需要太多时间。
          【解决方案7】:

          我会这样做:

          is_header = not any(cell.isdigit() for cell in csv_table[0])
          

          给定一个 CSV 表 csv_table,抓取顶部(第零)行。遍历单元格并检查它们是否包含任何纯数字字符串。如果是这样,它不是标题。在整个表达式前用not 否定它。

          结果:

          In [1]: not any(cell.isdigit() for cell in ['2','1'])
          Out[1]: False
          
          In [2]: not any(cell.isdigit() for cell in ['2','gravy'])
          Out[2]: False
          
          In [3]: not any(cell.isdigit() for cell in ['gravy','gravy'])
          Out[3]: True
          

          【讨论】:

            猜你喜欢
            • 2011-10-30
            • 2019-06-10
            • 1970-01-01
            • 2012-08-30
            • 1970-01-01
            • 2021-10-27
            • 2011-02-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多