Это более быстрый способ удаления строки Excel с использованием openpyxl? - PullRequest
0 голосов
/ 17 марта 2020

У меня есть список номеров строк Excel, которые я хочу удалить с длиной 2138 с использованием Openpyxl. Вот код:

delete_this_row = [1,2,....,2138]

for delete in delete_this_row:
    worksheet.delete_rows(delete)

Но это слишком медленно. Для завершения sh процесса требуется 45 секунд до 1 минуты.

Это более быстрый способ выполнить задачу?

1 Ответ

2 голосов
/ 17 марта 2020

Почти всегда более быстрый способ что-то сделать. Иногда стоимость слишком высока, но не в этом случае, я подозреваю: -)

Если вы хотите удалить только ряд смежных строк, вы можете просто использовать:

worksheet.delete_rows(1, 2138)

Документация здесь , скопированная ниже для полноты:

delete_rows(idx, amount=1): Удалить строку или строки из row==idx.

Ваше решение идет медленно, так как , каждый каждый раз, когда вы удаляете одну строку, она должна сдвинуть все ниже этой точки на одну строку, а затем удалить последнюю строку.

Передав счетчик строк вместо этого он выполняет одно смещение, сдвигая строки 2139..max прямо до строк 1..max-2138, а затем удаляет все строки, которые находятся ниже max-2138.

Это может быть примерно В 2138 раз быстрее, чем у вас сейчас: -)


Если в вашем массиве произвольных номеров строк, вы все равно можете использовать этот подход, чтобы максимально оптимизировать его.

Идея состоит в том, чтобы сначала превратить ваш список строк в список кортежей, в котором каждый кортеж имеет: * 10 38 *

  • начальный ряд; и
  • количество строк, которые нужно удалить оттуда.

В идеале вы должны сгенерировать это в обратном порядке, чтобы вы могли просто обработать его как есть. В следующем фрагменте показано, как вы могли бы сделать это, при этом вызовы openpyxl печатались, а не вызывались:

def reverseCombiner(rowList):
    # Don't do anything for empty list. Otherwise,
    # make a copy and sort.

    if len(rowList) == 0: return []
    sortedList = rowList[:]
    sortedList.sort()

    # Init, empty tuple, use first item for previous and
    # first in this run.

    tupleList = []
    firstItem = sortedList[0]
    prevItem = sortedList[0]

    # Process all other items in order.

    for item in sortedList[1:]:
        # If start of new run, add tuple and use new first-in-run.

        if item != prevItem + 1:
            tupleList = [(firstItem, prevItem + 1 - firstItem)] + tupleList
            firstItem = item

        # Regardless, current becomes previous for next loop.

        prevItem = item

    # Finish off the final run and return tuple list.

    tupleList = [(firstItem, prevItem + 1 - firstItem)] + tupleList
    return tupleList

# Test data, hit me with anything :-)

myList = [1, 70, 71, 72, 98, 21, 22, 23, 24, 25, 99]

# Create tuple list, show original and that list, then process.

tuples = reverseCombiner(myList)
print(f"Original: {myList}")
print(f"Tuples:   {tuples}\n")
for tuple in tuples:
    print(f"Would execute: worksheet.delete_rows({tuple[0]}, {tuple[1]})")

Вывод:

Original: [1, 70, 71, 72, 98, 21, 22, 23, 24, 25, 99]
Tuples:   [(98, 2), (70, 3), (21, 5), (1, 1)]

Would execute: worksheet.delete_rows(98, 2)
Would execute: worksheet.delete_rows(70, 3)
Would execute: worksheet.delete_rows(21, 5)
Would execute: worksheet.delete_rows(1, 1)
...