У меня есть 638 файлов Excel в каталоге размером около 3000 КБ каждый. Я хочу объединить их все вместе, надеюсь, только с помощью Python или командной строки (никаких других программ или языков программирования).
По сути, это часть более крупного процесса, который включает в себя некоторые простые манипуляции с данными, и я хочу, чтобы все это было выполнимо, просто запустив один файл Python (или дважды щелкнув пакетный файл).
Я пробовал варианты кода ниже - Pandas, openpyxl и xlrd, и они, кажется, имеют примерно одинаковую скорость. Для преобразования в csv, похоже, требуется VBA, в который я не хочу вникать.
temp_list=[]
for filename in os.listdir(filepath):
temp = pd.read_excel(filepath + filename,
sheet_name=X, usecols=fields)
temp_list.append(temp)
Существуют ли более простые решения командной строки для преобразования их в файлы csv или объединения в один документ Excel? Или это в значительной степени все, просто использование основных библиотек для чтения отдельных файлов?
Да, это оно. Я думаю, вы могли бы распараллелить это, вот и все.
Вместо использования df.append()
попробуйте импортировать файлы Excel в массив dfs, а затем используйте pd.concat()
для их объединения.
Вы также можете разобрать csv с помощью powershell, если не хотите связываться с vba. Это на самом деле довольно легко.
Трудно превзойти openpyxl в режиме только для чтения и только для значений по скорости.
.xls(x)
— это очень (слишком) сложный формат с множеством функций и причуд, накопленных за годы, и поэтому его довольно сложно разобрать. И он никогда не был рассчитан на скорость или большие объемы данных, а скорее на простоту использования для деловых людей.
Таким образом, с вашим количеством файлов лучше всего преобразовать их в .csv
или другой удобный для анализа формат (или использовать такой формат для обмена данными в первую очередь) - и предпочтительно сделать это до, который вы получите для обработки. их -- например по прибытии файла.
Например. вот как вы можете сохранить первый лист .xls(x)
в .csv
с pywin32
, используя COM-интерфейс Excel:
import win32com.client
# Need the typelib metadata to have Excel-specific constants
x = win32com.client.gencache.EnsureDispatch("Excel.Application")
# Need to pass full paths, see https://stackoverflow.com/questions/16394842/excel-can-only-open-file-if-using-absolute-path-why
w = x.Workbooks.Open("<full path to file>")
s = w.Worksheets(1)
s.SaveAs("<full path to file without extension>",win32com.client.constants.xlCSV)
w.Close(False)
Параллельный запуск обычно не дает никакого эффекта, поскольку один и тот же серверный процесс будет использоваться повторно. Вы можете принудительно создать отдельный процесс для каждого пакета в соответствии с Как я могу заставить python (используя win32com) создать новый экземпляр excel?.
Чтобы добавить к этому ответу, вы можете попытаться найти инструмент командной строки, отличный от Python, который преобразует файлы xls (x) в csv или tsv и делает это быстро (потому что он написан на чем-то более быстром, чем Python), а затем объединить преобразованные файлы используя простой cat
(убедитесь, что вы опускаете заголовки!). В идеале вам нужно что-то, что принимает несколько имен файлов или шаблон подстановочных знаков при одном вызове. Проверьте некоторые из этих вариантов: linoxid.com/linux-how-to/…
@Avish Скорость Python здесь не имеет значения, потому что вся тяжелая работа выполняется Excel.
Это делается в Excel, если вы используете COM-интерфейс Excel для чтения XLSX. В ОП используются панды read_excel
, которые (надеюсь?) используют не Excel для чтения файлов, а какую-то другую реализацию. Я пытаюсь предложить прочитать его с помощью другого инструмента командной строки, который быстрее читает файлы Excel, чем Excel или панды.
Кажется, что путь к файлу в workbooks.Add(<file>)
по какой-то причине по умолчанию имеет значение «Пользователи/пользователь/Документы», хотя все мои файлы и код находятся в пути, полностью отделенном от «Документов». Это приводит к ошибке com_error, которая спрашивает меня, были ли файлы перемещены или заменены. Связано ли это с каким-либо из шагов, ведущих к этому моменту, например win32com.client.gencache.EnsureDispatch("Excel.Application")
?
@ksoangxhc Да, вам нужно указать полный путь, см. stackoverflow.com/questions/16394842/…, почему. Я также изменил код, чтобы использовать Open
. (Add
с параметром предназначен для создания из шаблона, что я и сделал в своем последнем проекте, поэтому он как бы застрял у меня в голове; хотя в вашем конкретном случае нет никакой разницы).
@ksoangxhc Если ответ решил проблему, рассмотрите ее как принятие.
Насколько я понимаю, ваша самая большая проблема - это скорость обработки?