通过 openpyxl 选择数字列值更改符号的行
Selecting rows where a numeric column value change sign through openpyxl
我正在学习 Python 和 openpyxl 以在大型 xlsx 工作簿上进行数据分析。我有一个 for
循环,可以迭代整个列。下面是一些示例数据:
ROW: VALUE:
1 1
2 2
3 3
4 4
5 -4
6 -1
7 -6
8 2
9 3
10 -3
我想打印出值从正数变为负数,反之亦然的那一行。因此在上面的示例中,第 5、8 和 10 行将在控制台中打印。如何在 for
循环中使用 if
语句来遍历 openpyxl 上的列?
到目前为止,我可以打印一列中的所有单元格:
import openpyxl
wb = openpyxl.load_workbook('ngt_log.xlsx')
sheet = wb.get_sheet_by_name('sheet1')
for i in range(1, 10508, 1): # 10508 is the length of the column
print(i, sheet.cell(row=i, column=6).value)
我的想法是在 for
循环中添加一个 if
语句:
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i > 0 and (i+1) < 0) or (i < 0 and (i+1) > 0)):
print((i+1), sheet.cell(row=i, column=6).value)
但这不起作用。我是否正确地制定了 if
语句?
我觉得你的说法自相矛盾
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i greater than 0 and (i+1) less than 0) or (i less than 0 and (i+1) greater than
0)):
print((i+1), sheet.cell(row=i, column=6).value)
我用简单的英语写了 > 和 < 符号,但如果 i 大于 0,则 i + 1 永远不会小于 0,反之亦然,所以它们永远不会起作用,因为两者不可能都是真的
您需要先获取 sheet.cell 值,然后 然后 进行比较:
end_range = 10508
for i in range(1, end_range):
current, next = sheet.cell(row=i, column=6).value, sheet.cell(row=i+1, column=6).value
if current > 0 and next < 0 or current < 0 and next > 0:
print(i+1, next)
我很确定数学库中有一个 sign() 函数,但有点矫枉过正。如果值为 0,您可能还想弄清楚要做什么。
您可以将规则写入 select 符号已更改的行,并将它们放入生成器表达式中,而无需使用额外的内存,如下所示:
pos = lambda x: x>=0
keep = lambda s, c, i, v: pos(s[c][x].value)!=pos(v.value)
gen = (x+1 for x, y in enumerate(sheet['f']) if x>0 and keep(sheet, 'f', x-1, y))
然后,当您需要知道符号已更改的行时,只需按如下方式迭代 gen
:
for row in gen:
# here you use row
您可以使用标志来检查正面和负面。
ws = wb['sheet1'] # why people persist in using long deprecated syntax is beyond me
flag = None
for row in ws.iter_rows(max_row=10508, min_col=6, max_col=6):
cell = row[0]
sign = cell.value > 0 and "positive" or "negative"
if flag is not None and sign != flag:
print(cell.row)
flag = sign
我正在学习 Python 和 openpyxl 以在大型 xlsx 工作簿上进行数据分析。我有一个 for
循环,可以迭代整个列。下面是一些示例数据:
ROW: VALUE:
1 1
2 2
3 3
4 4
5 -4
6 -1
7 -6
8 2
9 3
10 -3
我想打印出值从正数变为负数,反之亦然的那一行。因此在上面的示例中,第 5、8 和 10 行将在控制台中打印。如何在 for
循环中使用 if
语句来遍历 openpyxl 上的列?
到目前为止,我可以打印一列中的所有单元格:
import openpyxl
wb = openpyxl.load_workbook('ngt_log.xlsx')
sheet = wb.get_sheet_by_name('sheet1')
for i in range(1, 10508, 1): # 10508 is the length of the column
print(i, sheet.cell(row=i, column=6).value)
我的想法是在 for
循环中添加一个 if
语句:
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i > 0 and (i+1) < 0) or (i < 0 and (i+1) > 0)):
print((i+1), sheet.cell(row=i, column=6).value)
但这不起作用。我是否正确地制定了 if
语句?
我觉得你的说法自相矛盾
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i greater than 0 and (i+1) less than 0) or (i less than 0 and (i+1) greater than
0)):
print((i+1), sheet.cell(row=i, column=6).value)
我用简单的英语写了 > 和 < 符号,但如果 i 大于 0,则 i + 1 永远不会小于 0,反之亦然,所以它们永远不会起作用,因为两者不可能都是真的
您需要先获取 sheet.cell 值,然后 然后 进行比较:
end_range = 10508
for i in range(1, end_range):
current, next = sheet.cell(row=i, column=6).value, sheet.cell(row=i+1, column=6).value
if current > 0 and next < 0 or current < 0 and next > 0:
print(i+1, next)
我很确定数学库中有一个 sign() 函数,但有点矫枉过正。如果值为 0,您可能还想弄清楚要做什么。
您可以将规则写入 select 符号已更改的行,并将它们放入生成器表达式中,而无需使用额外的内存,如下所示:
pos = lambda x: x>=0
keep = lambda s, c, i, v: pos(s[c][x].value)!=pos(v.value)
gen = (x+1 for x, y in enumerate(sheet['f']) if x>0 and keep(sheet, 'f', x-1, y))
然后,当您需要知道符号已更改的行时,只需按如下方式迭代 gen
:
for row in gen:
# here you use row
您可以使用标志来检查正面和负面。
ws = wb['sheet1'] # why people persist in using long deprecated syntax is beyond me
flag = None
for row in ws.iter_rows(max_row=10508, min_col=6, max_col=6):
cell = row[0]
sign = cell.value > 0 and "positive" or "negative"
if flag is not None and sign != flag:
print(cell.row)
flag = sign