通过 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