此代码迭代 Excel 电子表格并找到能量为零的特定列,然后通过计算连续零值的第一次和最后一次出现之间的差异来计算该零能量值周期的持续时间。
我遇到的问题是:当有多个连续的零行时,代码会停止并且永远不会提供输出。
我发现很难确定问题出在哪里。我可以得到一些帮助吗? 这是 Excel 文件中的示例数据。问题是当我们有超过几行零时如何获取输出。注意:实际 Excel 文件中的能量位于第 11 列,开始日期位于第 3 列,结束日期位于第 5 列,如代码所示。
开始日期 | 结束日期 | 能源 |
---|---|---|
2023/1/1 10:54 | 2023/1/1 11:56 | 60 |
2023/1/1 13:28 | 2023/1/1 13:35 | 0 |
2023/1/1 19:02 | 2023/1/1 19:30 | 0 |
2023/1/1 21:03 | 2023/1/1 21:20 | 0 |
2023年1月1日21:35 | 2023/1/1 21:56 | 0 |
2023/1/1 22:23 | 2023/1/1 22:25 | 0 |
2023/1/2 08:34 | 2023/1/2 08:56 | 0 |
2023/1/2 09:04 | 2023/1/1 09:16 | 0 |
2023/1/2 09:14 | 2023/1/2 09:23 | 0 |
2023年1月2日10:05 | 2023/1/2 10:17 | 53 |
import datetime
import openpyxl
import collections
from itertools import islice
#import pandas
from openpyxl.workbook import Workbook
cpsd = ("Excel file")
cpsd_op = openpyxl.load_workbook(cpsd)
cpsd_s1 = cpsd_op['Session-2024']
cpsd_dcfc1 = openpyxl.Workbook()
sheet_dcfc1 = cpsd_dcfc1["Sheet"]
# ^ pulls excel file in, we want to use openpyxl over pandas for excel, since it takes less time
# cpsd = session data
max_col_og = cpsd_s1.max_column
max_row_og = cpsd_s1.max_row
max_col_nw = sheet_dcfc1.max_column
max_row_nw = sheet_dcfc1.max_row
print(max_row_og, max_col_og)
for i in range(1, max_col_og+1):
c = cpsd_s1.cell(row = 1, column= i)
sheet_dcfc1.cell(row=1, column=i).value = c.value
for i in range(1, max_col_og+1):
cell_obj = sheet_dcfc1.cell(row=1, column=i)
print(cell_obj.value)
def del_empt_row (sheet):
index_row = []
for i in range(1, sheet.max_row):
# define emptiness of cell
if sheet.cell(i, 1).value is None:
# collect indexes of rows
index_row.append(i)
# loop each index value
for row_del in range(len(index_row)):
sheet.delete_rows(idx=index_row[row_del], amount=1)
# exclude offset of rows through each iteration
index_row = list(map(lambda k: k - 1, index_row))
for j in range(1, max_row_og +1):
for i in range(1, max_col_og +1):
c = cpsd_s1.cell(row=j, column=1)
if (c.value == "PP/ Charger 2"):
k = cpsd_s1.cell(row=j, column=i)
sheet_dcfc1.cell(row=j, column=i).value = k.value
#print(k.value)
del_empt_row(sheet_dcfc1)
def enddate (sheet, row):
#returns the end date of the last row with energy = 0
for row2 in range(row, max_row_og + 1):
if (sheet.cell(row=row2, column=10).value != 0):
return [sheet.cell(row=row2-1, column=5).value,row2-1]
else:
enddate(sheet,row+1)
def consume(iterator, n):
#allows us to skip the energy = 0 rows that have already been counted, since python is weird about iteration skipping
#"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
zero_time = datetime.datetime(2023, 1, 1, 00, 00, 00, 00)
tot_time = datetime.datetime(2023, 1, 1, 00, 00, 00, 00)
#print(tot_time)
range_x = enumerate(sheet_dcfc1.iter_rows())
for row_num, row in range_x:
# calculates total time for t-outage provided that there are no empty rows.
print(row_num)
if (row[9].value == 0):
strt_date = row[2].value
print(strt_date)
strt_row = row_num
end_date_arr = enddate(sheet_dcfc1,row_num+1)
end_date = end_date_arr[0]
print(end_date)
time = end_date-strt_date
consume(range_x, end_date_arr[1]-strt_row)
# print(row_num)
#print(str(row) + "does row change?")
tot_time += time
# print(time)
print(tot_time-zero_time)
# prints total time for t-outage provided that there are no empty rows.
在代码中包含一些注释来解释每个部分的作用会很有帮助。但据我所知,您正在将原始工作簿中的标题添加到新工作簿中(然后阅读/打印这些标题)。
然后有一个循环寻找值为“PP/ Charger 2”的单元格
您的帖子中没有提到这一点,也没有在提供的表格中。而且循环也是错误的。
for j in range(1, max_row_og +1):
for i in range(1, max_col_og +1):
c = cpsd_s1.cell(row=j, column=1)
if (c.value == "PP/ Charger 2"):
k = cpsd_s1.cell(row=j, column=i)
sheet_dcfc1.cell(row=j, column=i).value = k.value
您设置 j 来计算原始工作表中的行数,设置 i 来计算列数,然后
c = cpsd_s1.cell(row=j, column=1)
。所以这意味着它总是在同一列 (A) 中查找,“column=1”。想必这应该是“column=i”如果上一节确实找到“PP/ Charger 2”值,则会将该值复制到新工作表中的“相同”单元格中。然后,代码运行删除操作,其目的是删除空行,假设“PP/ Charger 2”可能位于任何行上。虽然此删除实现了它,但它也删除了之前写入的标头。如果只需在原始工作表中每次出现时将该值写入页面一次,则可以使用 Openpyxl“追加”,以便每个值都将写入下一个未使用的行。无论哪种方式,都可以将值逐行添加到新工作表中,而无需删除空行。确切的实现将取决于预期在哪里找到此文本。 然后代码循环所有行中所有单元格的列表,专门在第 9 行中查找 0 值,
row[9].value == 0):
大概这是在寻找能量栏中的 0 值。但是,您声明Energy 位于第 11 列
range_x = enumerate(sheet_dcfc1.iter_rows())