Я запускаю код, чтобы попытаться извлечь длину каждого файла в каталоге.
Я не могу понять, почему я получаю сообщение об ошибке: KeyError: "There is no item named 'Test1' in the archive"
Код:
from io import BytesIO
from pathlib import Path
from zipfile import ZipFile
import pandas as pd
def process_files(files: list) -> pd.DataFrame:
file_mapping = {}
for file in files:
data_mapping = pd.read_excel(BytesIO(ZipFile(file).read(Path(file).stem)), sheet_name=None)
row_counts = []
for sheet in list(data_mapping.keys()):
row_counts.append(len(data_mapping.get(sheet)))
file_mapping.update({file: sum(row_counts)})
frame = pd.DataFrame([file_mapping]).transpose().reset_index()
frame.columns = ["file_name", "row_counts"]
return frame
path = r'//Stack/Over/Flow/testfiles/'
zip_files = (str(x) for x in Path(path).glob("*.zip"))
df = process_files(zip_files)
print(df)
мои файлы:
внутри test1 почтовый индекс:
любая помощь будет оценена.
Изменить. Как мне применить код к zip-файлам в таких подкаталогах? Таким образом, в 2022–05 годах будут zip-файлы, а в 2022-06 годах — zip-файлы и т. д.






Для каждого файла в вашем архиве вы вызываете эту строку:
ZipFile(file).read(Path(file).stem)
Это означает, что в каждом zip-файле, заданном file, у вас должен быть файл в архиве с тем же именем, но без расширения (т. Е. основа).
Итак, чтобы это работало, вам нужно иметь такую структуру:
test1.zip
test1
test2.zip
test2
Вместо этого у вас есть файл TestInside1.xls, сильно отличающийся от имени файла test1. У вас есть несколько вариантов создания действительных путей для имен файлов внутри zip-архива — например, вы можете использовать ZipFile.namelist.
Например, вы можете заменить это:
data_mapping = pd.read_excel(BytesIO(ZipFile(file).read(Path(file).stem)), sheet_name=None)
с этим:
archive = ZipFile(file)
# find file names in the archive which end in `.xls`, `.xlsx`, `.xlsb`, ...
files_in_archive = archive.namelist()
excel_files_in_archive = [
f for f in files_in_archive if Path(f).suffix[:4] == ".xls"
]
# ensure we only have one file (otherwise, loop or choose one somehow)
assert len(excel_files_in_archive) == 1
# read in data
data_mapping = pd.read_excel(
BytesIO(archive.read(excel_files_in_archive[0])),
sheet_name=None,
)
вы определенно можете свободно просматривать zipfile docs и другие вопросы о переполнении стека, которые определенно отвечают на этот вопрос. вы также можете использовать полный внутренний путь, чтобы указать все, что вы хотите прочитать из zip-файла. но я позволю вам провести это (легкое) исследование - я ответил на вопрос, как вы его написали. расширение ответа на несколько подпапок - это просто вопрос зацикливания.
Спасибо! это прекрасно работает. Однако как это сделать для подпапок? Смотрите мою правку.