【问题标题】:How to check if .xls and .csv files are empty如何检查 .xls 和 .csv 文件是否为空
【发布时间】:2017-07-21 02:28:17
【问题描述】:

问题 1:如何检查整个 .xls 或 .csv 文件是否为空。这是我正在使用的代码:

try:
    if os.stat(fullpath).st_size > 0:
       readfile(fullpath)
    else:
       print "empty file"
except OSError:
    print "No file"

一个空的 .xls 文件的大小大于 5.6kb,因此它是否有任何内容并不明显。 如何检查 xls 或 csv 文件是否为空?

问题2:我需要检查文件头。 如何告诉python只有一行标题的文件是空的?

import xlrd
def readfile(fullpath)
    xls=xlrd.open_workbook(fullpath)  
    for sheet in xls.sheets():
        number_of_rows = sheet.nrows 
        number_of_columns = sheet.ncols
        sheetname = sheet.name
        header = sheet.row_values(0) #Then if it contains only headers, treat it as empty.

这是我的尝试。如何继续使用此代码?

请为这两个问题提供解决方案。提前致谢。

【问题讨论】:

    标签: python python-2.7 csv xls xlrd


    【解决方案1】:

    这在 pandas 中使用 .empty 方法很简单。这样做

    import pandas as pd
    
    df = pd.read_csv(filename) # or pd.read_excel(filename) for xls file
    df.empty # will return True if the dataframe is empty or False if not.
    

    对于只有标题的文件,这也将返回 True,如

    >> df = pd.DataFrame(columns = ['A','B'])
    >> df.empty
       True
    

    【讨论】:

    • 感谢您的回答。我正在使用 xlrd,我不想安装任何其他软件包,例如 panda
    【解决方案2】:

    问题 1:如何检查整个 .xls 文件是否为空。

    def readfile(fullpath):
    
        xls = xlrd.open_workbook(fullpath)
    
        is_empty = None
    
        for sheet in xls.sheets():
            number_of_rows = sheet.nrows
    
            if number_of_rows == 1:
                header = sheet.row_values(0)  
                # then If it contains only headers I want to treat as empty
                if header:
                    is_empty = False
                    break
    
            if number_of_rows > 1:
                is_empty = False
                break
    
            number_of_columns = sheet.ncols
            sheetname = sheet.name
    
        if is_empty:
            print('xlsx ist empty')
    

    问题2:我如何检查文件的标题。如果文件只有一个标题(我的意思是只有一行),我需要将文件视为空。我该怎么做。

    import csv
    with open('test/empty.csv', 'r') as csvfile:
        csv_dict = [row for row in csv.DictReader(csvfile)]
        if len(csv_dict) == 0:
            print('csv file is empty')
    

    用 Python:3.4.2 测试

    【讨论】:

    • 可能你的答案是对的,但我也需要检查 csv ans xls
    • 对于 csv,您不需要遍历所有行,也不需要使用 DictReader 解析。您可以检查文件中的第二行是否为空。 f.readline() == b''。查看我的答案以获取完整示例。
    【解决方案3】:

    我认为 Stackoverflow 当时不允许 2 个问题,但让我给你我对 Excel 部分的答案

    import xlrd
    from pprint import pprint
    
    wb = xlrd.open_workbook("temp.xlsx")
    
    empty_sheets = [sheet for sheet in wb.sheets() if sheet.ncols == 0]
    non_empty_sheets = [sheet for sheet in wb.sheets() if sheet.ncols > 0]
    
    # printing names of empty sheets
    pprint([sheet.name for sheet in empty_sheets])
    
    # writing non empty sheets to database 
    pass # write code yourself or ask another question 
    

    关于标题:让我给你一点提示,测试sheet.nrows == 1

    【讨论】:

    • 你说要同时检查所有工作表。但是如果工作表 1 有数据而工作表 2 是空的。那我该怎么办。
    • @bobmarti 你是什么意思?我们不知道你想做什么!您只想拥有不为空的床单吗?
    • 我想检查所有的工作表和空工作表视为空工作表值存储到数据库中
    • @bobmarti 我真的不明白你的意思。
    • 我想检查 excel 文件中的所有工作表。然后我需要哪些工作表是空的,然后打印它是空的。如果任何工作表不为空,则保存到数据库\
    【解决方案4】:

    对于您的 excel 代码,我喜欢有人提出的 pandas 解决方案,但是如果您在工作并且无法安装它,那么我认为您几乎可以使用您所采用的代码方法。您有一个遍历每张纸的循环。因此,您可以测试每张工作表中的行,然后在为空时采取适当的措施,如下所示:

    import xlrd
    
    xlFile = "MostlyEmptyBook.xlsx"
    
    def readfile(xlFile):
        xls=xlrd.open_workbook(xlFile)  
        for sheet in xls.sheets():
            number_of_rows = sheet.nrows 
            number_of_columns = sheet.ncols
            sheetname = sheet.name
            header = sheet.row_values(0) #then If it contains only headers I want to treat as empty
            if number_of_rows <= 1:
                # sheet is empty or has just a header
                # do what you want here
                print(xlFile + "is empty.")
    

    注意:我为文件名添加了一个变量,以便在使用时更容易在整个代码中的一个位置进行更改。我还在你的函数声明中添加了:,但它缺少它。如果您希望测试只有标题(我的包含完全空白页),则将 &lt;= 更改为 ==

    关于相关的 csv 问题。 csv 只是一个文本文件。我们可以合理地确定一个文件是空的,除了标题使用如下编码方法。我会在文件样本上尝试这段代码,你可能想调整我的数学逻辑。例如,在 if 比较中使用 + 1 而不是我所拥有的 *1.5 可能就足够了。我的想法是使用空格,或者如果错误地包含了一些字符,这将是一个很好的文件大小缓冲 + 编码逻辑中给出的第二行测试中的字符。

    这是假设您想在将一些大文件加载到计算机之前知道文件是否为空的假设。如果该假设是错误的,您可以使用我的测试逻辑,然后保持文件打开,甚至读入更多代码以确保在标题之后没有空行后跟其他内容(在格式错误的输入文件中) :

    import os
    
    def convert_bytes(num):
        """
        this function will convert bytes to MB.... GB... etc
        """
        for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
            if num < 1024.0:
                return "%3.1f %s" % (num, x)
            num /= 1024.0
    
    
    def file_size(file_path):
        """
        this function will return the file size
        """
        if os.path.isfile(file_path):
            file_info = os.stat(file_path)
            return convert_bytes(file_info.st_size)
    
    
    # testing if a csv file is empty in Python (header has bytes so not zero)
    
    fileToTest = "almostEmptyCSV.csv"
    
    def hasContentBeyondHeader(fileToTest):
        answer = [ True, 0, 0, 0]
        with open(fileToTest) as f:
            lis = [ f.readline(), f.readline() ] 
            answer[1] = len(lis[0])                # length header row
            answer[2] = len(lis[1])                # length of next row
            answer[3] = file_size(fileToTest)      # size of file
    
            # these conditions should be high confidence file is empty or nearly so
            sizeMult = 1.5   # test w/ your files and adjust as appropriate (but should work)
            charLimit = 5
    
            if answer[1] * sizeMult > answer[2] and answer[2] == 0:
                answer[0] = False
            elif answer[1] * sizeMult > answer[2] and answer[2] < charLimit:
                # separate condition in case you want to remove it
                # returns False if only a small number of chars (charLimit) on 2nd row
                answer[0] = False
            else:
                answer[0] = True   # added for readability (or delete else and keep default)         
    
            f.close()
        return answer
    
    hasContentBeyondHeader(fileToTest)  # False if believed to be empty except for header
    

    在测试期间,readline 命令从文件中提取了以下内容:

    ['year,sex,births\n', '']
    

    样本输出:

    [True, 16, 0, '17.0 bytes']
    

    这种方法意味着您可以在它返回的列表的[0] 元素中访问真/假的测试结果。附加元素使您可以获取有关程序决策输入的信息,以防您以后想对其进行调整。

    此代码以自定义文件大小函数开头。如果您正在寻找更短的代码,您可能可以根据您的喜好将其替换为这个。这将取代前两个小函数:

    import os    
    os.path.getsize(fullpathhere)
    

    【讨论】:

      【解决方案5】:

      这样的事情怎么样:

      file = open(path, "r")
      file_content = file.read()
      file.close()
      if file_content == "":
          print("File '{}' is empty".format(path))
      else:
          rows = file_content.split("\n", 1)
          if rows[1] == "":
              print("File '{}' contains headers only.".format(path))
      

      path 是您的 xls 或 csv 文件的路径。

      【讨论】:

      • 事后,我不确定这段代码是否适用于 xls 文件,因为这种文件格式的特殊编码......
      【解决方案6】:

      对于您的问题:

      问题2:我需要检查文件头。如何告诉python只有一行标题的文件是空的?

      您可以只检查文件中的行。

      with open('empty_csv_with_header.csv') as f:
          f.readline()  # skip header
          line = f.readline()
          if line == b'':
              print('Empty csv')
      

      【讨论】:

        【解决方案7】:

        试试这个可以解决问题。 并非所有空的 CSV 文件都是 0 字节。这在这种情况下也有效。

        import os
        from os.path import isfile
        import pandas
        
        if isfile(PASSWORD_MANAGER_FILE):
            try:
                pandas.read_csv(PASSWORD_MANAGER_FILE)
            except pandas.errors.EmptyDataError:
                os.remove(PASSWORD_MANAGER_FILE)
        

        【讨论】:

          猜你喜欢
          • 2013-10-25
          • 1970-01-01
          • 2021-03-21
          • 1970-01-01
          • 1970-01-01
          • 2012-08-22
          • 2016-02-22
          • 2015-10-14
          • 2023-02-16
          相关资源
          最近更新 更多