web-dev-qa-db-fra.com

Comment vérifier si les fichiers .xls et .csv sont vides

Question 1: Comment puis-je vérifier si un fichier .xls ou .csv entier est vide? C'est le code que j'utilise:

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

Un fichier .xls vide a une taille supérieure à 5,6 Ko. Il n’est donc pas évident qu’il ait un contenu quelconque. Comment puis-je vérifier si un fichier xls ou csv est vide?

Question 2: Je dois vérifier l'en-tête du fichier. Comment puis-je dire à Python que les fichiers qui ne sont qu'une rangée d'en-têtes sont vides?

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.

Ceci est ma tentative. Comment continuer avec ce code?

Veuillez fournir une solution aux deux questions. Merci d'avance.

6
bob marti

C'est simple dans les pandas avec la méthode .empty . Faire ceci

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.

Ceci renverra également la valeur True pour un fichier avec uniquement des en-têtes, comme dans 

>> df = pd.DataFrame(columns = ['A','B'])
>> df.empty
   True
8
Некто

Question 1: Comment je vérifie que tout le fichier .xls est vide. 

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: Comment vérifier l'en-tête du fichier .Si le fichier n'a qu'un en-tête (je ne parle que d'une seule ligne), je dois traiter le fichier est vide .Comment puis-je le faire? 

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

Testé avec Python: 3.4.2

2
stovfl

Pour votre code Excel, j'aime bien la solution pandas que quelqu'un a proposée, mais si vous êtes au travail et que vous ne pouvez pas l'installer, je pense que vous y étiez presque avec l'approche de code que vous utilisiez. Vous avez une boucle traversant chaque feuille. Vous pouvez donc tester les lignes de chaque feuille, puis prendre les mesures appropriées si elles sont vides, comme ceci:

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

Remarque: j'ai ajouté une variable pour le nom de fichier afin de faciliter la modification d'un seul emplacement dans le code lorsqu'il est utilisé. J'ai aussi ajouté : à la déclaration de votre fonction qui ne l’avait pas. Si vous souhaitez que le test ait uniquement un en-tête (le mien inclut une page entièrement vierge), remplacez <= par ==.

En ce qui concerne la question connexe de CSV. CSV est juste un fichier texte. Nous pouvons être raisonnablement certains qu'un fichier est vide à l'exception de l'en-tête utilisant une approche de codage comme celle qui suit. Je voudrais essayer ce code sur un échantillon de fichiers, et vous voudrez peut-être ajuster ma logique mathématique. Par exemple, il peut être suffisant d’utiliser + 1 sur la comparaison if si au lieu de *1.5 tel que je l’ai. Ma pensée concerne les espaces ou si quelques caractères étaient inclus par erreur, il s'agirait d'un bon coussin de taille de fichier + des caractères du test de deuxième ligne indiqués dans la logique de codage.

Cela a été écrit en partant du principe que vous voulez savoir si le fichier est vide avant de charger un fichier géant dans votre ordinateur. Si cette hypothèse est fausse, vous pouvez utiliser ma logique de test et ensuite garder le fichier ouvert, ou même lire davantage de code pour vous assurer qu'il n'y a pas de ligne vierge suivie de contenu supplémentaire après l'en-tête (dans un fichier d'entrée mal formaté) :

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

Pendant les tests, les commandes readline ont extrait ce contenu du fichier: 

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

exemple de sortie:

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

Cette approche signifie que vous pouvez accéder aux résultats du test qui sont True/False dans l'élément [0] de la liste renvoyée. Les éléments supplémentaires vous permettent d’obtenir des informations sur les entrées dans la prise de décision du programme au cas où vous souhaiteriez le modifier ultérieurement. 

Ce code commence par une fonction de taille de fichier personnalisée. Vous pouvez probablement remplacer cela par ceci en fonction de vos préférences si vous recherchez un code plus court. Cela remplacerait les deux premières fonctions minuscules:

import os    
os.path.getsize(fullpathhere)
1
TMWP

Je ne pense pas que Stackoverflow permette 2 questions à la fois mais laissez-moi vous donner ma réponse pour la partie 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 

À propos de l'en-tête: laissez-moi vous donner un petit indice, testez sheet.nrows == 1.

1
Elmex80s

qu'en est-il quelque chose comme ça:

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 est le chemin de votre fichier xls ou csv.

1
PurpleJo

Pour ta question:

Question 2: Je dois vérifier l'en-tête du fichier. Comment puis-je dire à Python que les fichiers ne contenant qu'une seule rangée d'en-têtes sont vides?

Vous pouvez simplement vérifier la ligne dans les fichiers.

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