Как преобразовать электронные таблицы OpenDocument в панду DataFrame?
Панды библиотеки Python могут читать электронные таблицы Excel и преобразовывать их в pandas.DataFrame
сpandas.read_excel(file)
команда. Под капотом он использует библиотеку xlrd, которая не поддерживает файлы ods.
Есть ли эквивалент pandas.read_excel
для одс файлов? Если нет, как я могу сделать то же самое для электронной таблицы с открытым документом (файл ods)? ODF используется LibreOffice и OpenOffice.
12 ответов
Это доступно изначально в pandas 0.25. Если у вас установлен odfpy (conda install odfpy ИЛИ pip install odfpy), вы можете сделать
pd.read_excel("the_document.ods", engine="odf")
Вы можете прочитать ODF (Open Document Format .ods
) документы в Python с использованием следующих модулей:
Используя ezodf, простой конвертер ODS-to-DataFrame может выглядеть так:
import pandas as pd
import ezodf
doc = ezodf.opendoc('some_odf_spreadsheet.ods')
print("Spreadsheet contains %d sheet(s)." % len(doc.sheets))
for sheet in doc.sheets:
print("-"*40)
print(" Sheet name : '%s'" % sheet.name)
print("Size of Sheet : (rows=%d, cols=%d)" % (sheet.nrows(), sheet.ncols()) )
# convert the first sheet to a pandas.DataFrame
sheet = doc.sheets[0]
df_dict = {}
for i, row in enumerate(sheet.rows()):
# row is a list of cells
# assume the header is on the first row
if i == 0:
# columns as lists in a dictionary
df_dict = {cell.value:[] for cell in row}
# create index for the column headers
col_index = {j:cell.value for j, cell in enumerate(row)}
continue
for j, cell in enumerate(row):
# use header instead of column index
df_dict[col_index[j]].append(cell.value)
# and convert to a DataFrame
df = pd.DataFrame(df_dict)
PS
Поддержка электронных таблиц ODF (*.ods) была запрошена на
pandas
средство отслеживания ошибок: https://github.com/pydata/pandas/issues/2311, но оно все еще не реализовано.ezodf
был использован в незавершенном PR9070 для реализации поддержки ODF в пандах. Этот PR сейчас закрыт (читайте PR для технического обсуждения), но он все еще доступен в качестве экспериментальной функции в этомpandas
вилка.- Есть также некоторые методы грубой силы для чтения непосредственно из кода XML ( здесь)
Вот быстрый и грязный хак, который использует модуль ezodf:
import pandas as pd
import ezodf
def read_ods(filename, sheet_no=0, header=0):
tab = ezodf.opendoc(filename=filename).sheets[sheet_no]
return pd.DataFrame({col[header].value:[x.value for x in col[header+1:]]
for col in tab.columns()})
Тестовое задание:
In [92]: df = read_ods(filename='fn.ods')
In [93]: df
Out[93]:
a b c
0 1.0 2.0 3.0
1 4.0 5.0 6.0
2 7.0 8.0 9.0
ЗАМЕТКИ:
- все другие полезные параметры, такие как
header
,skiprows
,index_col
,parse_cols
НЕ реализованы в этой функции - не стесняйтесь обновить этот вопрос, если вы хотите их реализовать ezodf
зависит отlxml
убедитесь, что он установлен
pandas теперь поддерживает файлы .ods. вы должны сначала установить модуль odfpy. тогда он будет работать как обычный файл .xls.
conda install -c conda-forge odfpyr
потом
pd.read_excel('FILE_NAME.ods', engine='odf')
Кажется, ответ - нет! И я бы охарактеризовал инструменты для чтения в ODS, все еще неровные. Если вы работаете в POSIX, возможно, стратегия экспорта в xlsx на лету перед использованием очень хороших инструментов импорта Pandas для xlsx:
unoconv -f xlsx -o tmp.xlsx myODSfile.ods
В целом мой код выглядит так:
import pandas as pd
import os
if fileOlderThan('tmp.xlsx','myODSfile.ods'):
os.system('unoconv -f xlsx -o tmp.xlsx myODSfile.ods ')
xl_file = pd.ExcelFile('tmp.xlsx')
dfs = {sheet_name: xl_file.parse(sheet_name)
for sheet_name in xl_file.sheet_names}
df=dfs['Sheet1']
Здесь fileOlderThan() - это функция (см. http://github.com/cpbl/cpblUtilities), которая возвращает true, если tmp.xlsx не существует или старше, чем файл.ods.
Другой вариант: read-ods-with-odfpy. Этот модуль принимает электронную таблицу OpenDocument в качестве входных данных и возвращает список, из которого можно создать DataFrame.
Если у вас есть только несколько файлов.ods для чтения, я бы просто открыл его в openoffice и сохранил как файл Excel. Если у вас много файлов, вы можете использовать unoconv
команда в Linux для программного преобразования файлов.ods в.xls ( с помощью bash)
Тогда это действительно легко прочитать с pd.read_excel('filename.xls')
В некоторых ответах указывалось, что для получения этой функции необходимы odfpy или другие внешние пакеты, но обратите внимание, что в последних версиях Pandas (текущая версия 1.1, август-2020) есть поддержка формата ODS в таких функциях, как pd.ExcelWriter() и pd.read_excel(). Вам нужно только указать соответствующий механизм "odf", чтобы иметь возможность работать с форматами файлов OpenDocument (.odf, .ods, .odt).
Мне повезло с пандами read_clipboard. Выделите ячейки, а затем скопируйте из Excel или Opendocument. В python запускаем следующее.
import pandas as pd
data = pd.read_clipboard()
Панды будут делать хорошую работу, основываясь на скопированных клетках.
Основываясь на ответе davidovitch (спасибо), я собрал пакет, который читает в файле.ods и возвращает DataFrame. Это не полная реализация в pandas
само по себе, например, его пиар, но он обеспечивает простое read_ods
функция, которая делает работу.
Вы можете установить его с pip install pandas_ods_reader
, Также можно указать, содержит ли файл строку заголовка или нет, а также указать пользовательские имена столбцов.
Существует поддержка чтения файлов Excel в Pandas (как xls, так и xlsx), см. Команду read_excel. Вы можете использовать OpenOffice, чтобы сохранить электронную таблицу как xlsx. Преобразование также можно выполнить автоматически в командной строке, по-видимому, используя параметр командной строки convert-to.
Чтение данных из xlsx позволяет избежать некоторых проблем (форматы даты, числовые форматы, юникод), с которыми вы можете столкнуться при первом преобразовании в CSV.
Если возможно, сохраните файл в формате CSV из приложения для работы с электронными таблицами, а затем используйте pandas.read_csv()
, IIRC, файл электронных таблиц "ods" на самом деле представляет собой файл XML, который также содержит довольно много информации о форматировании. Итак, если речь идет о табличных данных, сначала извлеките эти необработанные данные в промежуточный файл (в данном случае CSV), который затем можно будет проанализировать с другими программами, такими как Python/pandas.