AttributeError: Das Objekt 'ElementTree' hat kein Attribut 'getiterator', wenn versucht wird, eine Excel-Datei zu importieren
Das ist mein Code. Ich habe gerade jupyterlab installiert und dort die Excel-Datei hinzugefügt. Gleicher Fehler, wenn ich den Pfad dahin ändere, wo sich die Datei auf meinem System befindet. Ich kann anscheinend niemanden finden, der das gleiche Problem hatte, als er einfach eine Excel-Datei als Datenrahmen importierte.
Die Excel-Datei ist eine 3x26-Tabelle mit Schüler-, Kurs- und Ergebnisspalten mit Werten wie 101-105, AD, 1.0-9.9. Vielleicht liegt das Problem in der Excel-Datei?
Auf jeden Fall habe ich keine Ahnung, wie ich das beheben soll.
import pandas as pd
import numpy as np
df = pd.read_excel('student-results.xlsx')
Dies ist der Fehler, den ich bekomme:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-9d38e4d56bbe> in <module>
1 import pandas as pd
2 import numpy as np
----> 3 df = pd.read_excel('student-results.xlsx')
c:\python\lib\site-packages\pandas\util\_decorators.py in wrapper(*args, **kwargs)
294 )
295 warnings.warn(msg, FutureWarning, stacklevel=stacklevel)
--> 296 return func(*args, **kwargs)
297
298 return wrapper
c:\python\lib\site-packages\pandas\io\excel\_base.py in read_excel(io, sheet_name, header, names, index_col, usecols, squeeze, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, parse_dates, date_parser, thousands, comment, skipfooter, convert_float, mangle_dupe_cols)
302
303 if not isinstance(io, ExcelFile):
--> 304 io = ExcelFile(io, engine=engine)
305 elif engine and engine != io.engine:
306 raise ValueError(
c:\python\lib\site-packages\pandas\io\excel\_base.py in __init__(self, path_or_buffer, engine)
865 self._io = stringify_path(path_or_buffer)
866
--> 867 self._reader = self._engines[engine](self._io)
868
869 def __fspath__(self):
c:\python\lib\site-packages\pandas\io\excel\_xlrd.py in __init__(self, filepath_or_buffer)
20 err_msg = "Install xlrd >= 1.0.0 for Excel support"
21 import_optional_dependency("xlrd", extra=err_msg)
---> 22 super().__init__(filepath_or_buffer)
23
24 @property
c:\python\lib\site-packages\pandas\io\excel\_base.py in __init__(self, filepath_or_buffer)
351 self.book = self.load_workbook(filepath_or_buffer)
352 elif isinstance(filepath_or_buffer, str):
--> 353 self.book = self.load_workbook(filepath_or_buffer)
354 elif isinstance(filepath_or_buffer, bytes):
355 self.book = self.load_workbook(BytesIO(filepath_or_buffer))
c:\python\lib\site-packages\pandas\io\excel\_xlrd.py in load_workbook(self, filepath_or_buffer)
35 return open_workbook(file_contents=data)
36 else:
---> 37 return open_workbook(filepath_or_buffer)
38
39 @property
c:\python\lib\site-packages\xlrd\__init__.py in open_workbook(filename, logfile, verbosity, use_mmap, file_contents, encoding_override, formatting_info, on_demand, ragged_rows)
128 if 'xl/workbook.xml' in component_names:
129 from . import xlsx
--> 130 bk = xlsx.open_workbook_2007_xml(
131 zf,
132 component_names,
c:\python\lib\site-packages\xlrd\xlsx.py in open_workbook_2007_xml(zf, component_names, logfile, verbosity, use_mmap, formatting_info, on_demand, ragged_rows)
810 del zflo
811 zflo = zf.open(component_names['xl/workbook.xml'])
--> 812 x12book.process_stream(zflo, 'Workbook')
813 del zflo
814 props_name = 'docprops/core.xml'
c:\python\lib\site-packages\xlrd\xlsx.py in process_stream(self, stream, heading)
264 self.tree = ET.parse(stream)
265 getmethod = self.tag2meth.get
--> 266 for elem in self.tree.iter() if Element_has_iter else self.tree.getiterator():
267 if self.verbosity >= 3:
268 self.dump_elem(elem)
AttributeError: 'ElementTree' object has no attribute 'getiterator'
Antworten
Sie könnten versuchen, ein Argument zu verwenden engine="openpyxl". Es hat mir geholfen, das gleiche Problem zu lösen.
Der Fehler tritt auf, wenn pandas in python3.9 + verwendet wird, da der Code, xml.etree.ElementTree.Element.getiterator()der zuvor mit einer Warnung verworfen wurde , jetzt entfernt wurde.
Eine Problemumgehung besteht darin, eine andere Engine openpyxl zu installieren, um die Excel-Datei zu lesen, und Ihren Code zu ersetzen, der die Excel-Datei liest.
Zuerst,
pip3 install openpyxl
Dann pd.read_excel('student-results.xlsx')schreiben Sie stattpd.read_excel('student-results.xlsx', engine='openpyxl')
Referenz: Python Bug Tracker
Ich habe den gleichen Fehler mit xlrd (1.2.0) oder xlrd3 (1.0.0) ohne Pandas bekommen, aber mit Python 3.9. Folgendes könnte diejenigen interessieren, die nach einer Erklärung suchen:
Dies geschah nur, wenn defusedxml verfügbar war (in diesem Fall wird xlrd es verwenden). Aber es könnte umgangen werden, ohne eine der beteiligten Bibliotheken zu ändern:
import xlrd
xlrd.xlsx.ensure_elementtree_imported(False, None)
xlrd.xlsx.Element_has_iter = True
Die zweite Zeile stellt sicher, dass Element_has_iterbeim Öffnen einer Arbeitsmappe nicht zurückgesetzt wird, sodass sie auf True bleibt - wie in der dritten Zeile festgelegt. Wenn dies erledigt ist, verwendet xlrd iteranstelle des Absturzes die fehlenden getiterator.
Trotzdem stimme ich zu, dass die Umstellung auf openpyxl anstelle von xlrd eine sauberere Lösung ist, zumindest bis xlrd oder xlrd3 möglicherweise behoben werden. Openpyxl scheint aktiver entwickelt zu sein. In meinem Fall muss ich direkte Aufrufe an diese Bibliotheken anpassen. Es ist wahrscheinlich mehr Arbeit als nur openpyxl anstelle von xlrd einzugeben, um Pandas zu sagen, was es tun soll, aber ich werde es in Betracht ziehen.
Also ok mit @corridda, benutze openpyxl und andere haben Recht mit der Ursache, aber vielleicht erklärt dies ein bisschen mehr über die Ursachen.
Sie können die Problembeschreibung hier überprüfen . Sie führen Python 3.9 aus und verwenden die xlrd- Bibliothek, die die getiteratorMethode remove aufruft . Sie sollten Teil des Codes in der Datei von Ihrer finden „Trace zurück“ und ersetzen getiteratormit iter.
Möglicherweise müssen Sie die Python-Datei ausführen und diese Aufrufe mehrmals ersetzen.
Befolgen Sie die folgenden Schritte:
- Gehen Sie zu /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/xlrd
- Öffnen Sie die Datei xlsx.py in einem beliebigen Texteditor und ersetzen Sie die beiden Methoden getiterator () durch iter ().
- Laden Sie Ihr Jupiter-Notizbuch neu. Es wird klappen.
Dies zeigte sich für mich beim Upgrade auf Python 3.9. Der Unterschied scheint mit einer Kombination des Komprimierungsformats von xlsxDateien und der Ablehnung einer Iteratorfunktion zu zusammenhängen.
Für xlsxDokumente muss ich engine='openpyxl'beim Öffnen das Schlüsselwortargument angeben .
Dies ist nicht der Fall für csvoder xlsDokumente.
Installieren Sie openpyxl
$ pip3 install openpyxl
Öffnen xlsxund xlsDateien mit verschiedenen Engines.
from pathlib import Path
import pandas as pd
file_path = Path(file_name)
if file_path.suffix == '.xlsx':
df = pd.read_excel(file_name, engine='openpyxl')
elif file_path.suffix == '.xls':
df = pd.read_excel(file_name)
else:
# handle other file types
pass