Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用openpyxl删除Excel行有没有更快的方法?_Python_Performance_Openpyxl - Fatal编程技术网

Python 使用openpyxl删除Excel行有没有更快的方法?

Python 使用openpyxl删除Excel行有没有更快的方法?,python,performance,openpyxl,Python,Performance,Openpyxl,我有一个excel行号列表,我想使用Openpyxl删除长度为2138的行号。代码如下: delete_this_row = [1,2,....,2138] for delete in delete_this_row: worksheet.delete_rows(delete) 但是太慢了。完成此过程需要45秒到1分钟 这是完成任务的更快的方法吗?几乎总是有更快的方法来做某事。有时成本太高,但我怀疑不是在这种情况下:-) 如果只是要删除的一组连续行,则可以使用: worksheet.

我有一个excel行号列表,我想使用Openpyxl删除长度为2138的行号。代码如下:

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

for delete in delete_this_row:
    worksheet.delete_rows(delete)
但是太慢了。完成此过程需要45秒到1分钟

这是完成任务的更快的方法吗?

几乎总是有更快的方法来做某事。有时成本太高,但我怀疑不是在这种情况下:-)

如果只是要删除的一组连续行,则可以使用:

worksheet.delete_rows(1, 2138)
文件,为完整起见复制如下:

delete_行(idx,amount=1)
:从
row==idx
中删除一行或多行

您的解决方案很慢,因为每次删除一行时,它必须将该点下的所有内容向上移动一行,然后删除最后一行

通过传入行计数,它将执行一次移位,将行
2139..max
直接上移到行
1..max-2138
,然后删除
max-2138
以下的所有行

这可能比您现在的速度快2138倍:-)


如果数组中有任意行号,仍然可以使用此方法尽可能优化它

这里的想法是首先将行列表转换为元组列表,其中每个元组都有:

  • 起始行;及
  • 要从中删除的行数
理想情况下,您还可以按相反的顺序生成它,这样您就可以按原样处理它。下面的代码片段显示了如何在打印而不是调用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)

首先,感谢paxdiablo给出的答案:实际上,在我的例子中,设置的值是随机数。然后我进行反向排序,这样删除过程从最后一行开始,这样就不会弄乱整行。还有其他建议吗?@MuhammadDwiky:请看更新。您可以预处理任意列表以创建逆序的
{row,count}
元组列表,然后处理该列表以进行实际删除。例如,如果输入是
{1,3,5,7,9,…}
,它仍然可以退化为一行删除,但它将尽可能优化删除。哇,这太棒了。它节省了大约30秒:D非常感谢我的朋友!