如何检查 .xls 和 .csv 文件是否为空

How to check if .xls and .csv files are empty

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

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:我需要检查文件的header。 如何判断 python 只有一行 header 的文件是空的?

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.

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

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

这在 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.

对于只有 headers 的文件,这也 return 正确,如

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

我认为 Whosebug 当时不允许提出 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 

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

Question 1: How I check the entire .xls file are empty.

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')

Question 2: How I check header of the file .If the file has only a header(I mean only a single row) I need to treat the file is empty .How can I do that.

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

对于您的 excel 代码,我喜欢某人提出的 pandas 解决方案,但如果您在工作中无法安装它,那么我认为您几乎已经掌握了代码你正在采取的方法。你有一个遍历每个 sheet 的循环。因此,您可以测试每个 sheet 中的行,然后在空的情况下采取适当的措施,如下所示:

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.")

注意:我为文件名添加了一个变量,以便在使用时更容易在整个代码中的一个地方进行更改。我还在你的函数声明中添加了 : ,但它丢失了。如果您希望测试只有 header(我的包括完全空白的页面),则将 <= 更改为 ==

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

写这篇文章的前提是,在将某个大文件加载到计算机之前,您想知道文件是否为空。如果这个假设是错误的,您可以使用我的测试逻辑,然后保持文件打开,或者甚至读入更多代码以确保在 header 之后没有空行后跟其他内容(严重格式化输入文件):

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']

这种方法意味着您可以访问列表 returns 的 [0] 元素中的 True/False 测试结果。附加元素允许您获取有关程序 decision-making 输入的信息,以备日后对其进行调整。

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

import os    
os.path.getsize(fullpathhere)

像这样的事情怎么样:

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 文件的路径。

针对您的问题:

Question 2: I need to check the header of the file. How can I tell python that files which are just a single row of headers are empty?

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

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

试试这个可以解决问题。 并非所有空 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)