web-dev-qa-db-ja.com

.xlsファイルと.csvファイルが空かどうかを確認する方法

質問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ヘッダーが1行しかないファイルが空であることをどのように伝えることができますか?

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.

これが私の試みです。このコードを続行するにはどうすればよいですか?

両方の質問に対する解決策を提供してください。前もって感謝します。

7
bob marti

これは、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
9
Некто

質問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:ファイルのヘッダーを確認する方法。ファイルにヘッダーしかない場合(つまり、1つの行のみを意味します)、ファイルを空にする必要があります。どうすればよいですか。

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

3
stovfl

あなたの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.")

注:ファイル名の変数を追加して、使用時にコード全体で1か所で簡単に変更できるようにしました。関数宣言に:も追加しましたが、それがありませんでした。テストをヘッダーのみにする場合(完全に空白のページが含まれる場合)、<===に変更します。

関連するcsvの問題について。 csvは単なるテキストファイルです。次のようなコーディングアプローチを使用するヘッダーを除いて、ファイルが空であると合理的に確信できます。ファイルのサンプルでこのコードを試してみると、私の数学のロジックを調整したくなるかもしれません。たとえば、私が持っている+ 1ではなくif比較で*1.5を使用するだけで十分な場合があります。私の考えでは、空白を使用するか、いくつかの文字が誤って含まれている場合、これは適切なファイルサイズのクッション+コーディングロジックで指定された2行目の文字のテストになります。

これは、巨大なファイルをコンピュータにロードする前に、ファイルが空かどうかを知りたいという前提で書かれています。その仮定が間違っている場合は、テストロジックを使用してファイルを開いたままにするか、さらに多くのコードを読み込んで、ヘッダーの後に空白行がないことを確認してください(不適切な形式の入力ファイル) :

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]要素の真/偽であるテストの結果にアクセスできることを意味します。追加の要素により、後で微調整する場合に備えて、プログラムの意思決定への入力に関する情報を取得できます。

このコードは、カスタムファイルサイズ関数から始まります。短いコードを探している場合は、好みに応じてこれに置き換えることができます。これにより、最初の2つの小さな関数が置き換えられます。

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

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
Elmex80s

このようなものはどうですか?

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ファイルのパスです。

1
PurpleJo

あなたの質問:

質問2:ファイルのヘッダーを確認する必要があります。 pythonヘッダーが1行しかないファイルが空であることをどのように伝えることができますか?

ファイルの行をチェックするだけです。

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