Как найти активное количество элементов в одном столбце / строке, используя Openpyxl в Python? - PullRequest
0 голосов
/ 25 октября 2019

Я использую openpyxl.

  1. У меня есть базовая таблица ниже.

enter image description here

Я пытаюсь просто получить активное число элементов в определенном столбце, используя len () и фильтр, но все еще не получаю то, что я хотел.

Пример кода:

load_xls_file = open("./sample.xlsx", "r") 
wb = load_workbook(load_xls_file)
sheet = wb.get_sheet_by_name("Sheet")


rock = len(sheet['A'])

print '_code : Value of rock from spreadsheet is',rock 
print '_code : Values are', filter(None,sheet['A'])
print '_code : Values are', sheet['A'] 
print '_code : Values of b', len(sheet['B']) 

Вывод:

    _code : Value of rock from spreadsheet is 30
    _code : Values are (<Cell u'Sheet'.A1>, <Cell u'Sheet'.A2>, <Cell u'Sheet'.A3>, <Cell u'Sheet'.A4>, <Cell u'Sheet'.A5>, <Cell u'Sheet'.A6>, <Cell u'Sheet'.A7>, <Cell u'Sheet'.A8>, <Cell u'Sheet'.A9>, <Cell u'Sheet'.A10>, <Cell u'Sheet'.A11>, <Cell u'Sheet'.A12>, <Cell u'Sheet'.A13>, <Cell u'Sheet'.A14>, <Cell u'Sheet'.A15>, <Cell u'Sheet'.A16>, <Cell u'Sheet'.A17>, <Cell u'Sheet'.A18>, <Cell u'Sheet'.A19>, <Cell u'Sheet'.A20>, <Cell u'Sheet'.A21>, <Cell u'Sheet'.A22>, <Cell u'Sheet'.A23>, <Cell u'Sheet'.A24>, <Cell u'Sheet'.A25>, <Cell u'Sheet'.A26>, <Cell u'Sheet'.A27>, <Cell u'Sheet'.A28>, <Cell u'Sheet'.A29>, <Cell u'Sheet'.A30>)
    _code : Values are (<Cell u'Sheet'.A1>, <Cell u'Sheet'.A2>, <Cell u'Sheet'.A3>, <Cell u'Sheet'.A4>, <Cell u'Sheet'.A5>, <Cell u'Sheet'.A6>, <Cell u'Sheet'.A7>, <Cell u'Sheet'.A8>, <Cell u'Sheet'.A9>, <Cell u'Sheet'.A10>, <Cell u'Sheet'.A11>, <Cell u'Sheet'.A12>, <Cell u'Sheet'.A13>, <Cell u'Sheet'.A14>, <Cell u'Sheet'.A15>, <Cell u'Sheet'.A16>, <Cell u'Sheet'.A17>, <Cell u'Sheet'.A18>, <Cell u'Sheet'.A19>, <Cell u'Sheet'.A20>, <Cell u'Sheet'.A21>, <Cell u'Sheet'.A22>, <Cell u'Sheet'.A23>, <Cell u'Sheet'.A24>, <Cell u'Sheet'.A25>, <Cell u'Sheet'.A26>, <Cell u'Sheet'.A27>, <Cell u'Sheet'.A28>, <Cell u'Sheet'.A29>, <Cell u'Sheet'.A30>)
_code : Values of b 30

Ни len (), ни фильтр не предоставляют ожидаемое значение, т. Е. 7, а печатает максимальное значение 30 все время. Кроме того, даже когда я делаю, len (лист ['B']) все еще дает то же значение 30.

Я делаю какую-то простую ошибку? Пожалуйста, предоставьте ваши комментарии.

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

Вопрос : получить активное число элементов в определенном столбце


Рабочий лист :

Title   Title   Title   
1       3       4   
None    None    None    
1       3       4   
min_col = 1  # 'A'
val_counter = 0

# Iterate all Rows, starting at 'min_row='
# Iterate only ONE Column, therefore 'min_col=' and 'max_col=' have the same value
# Returns a Tuple of Column Values ((value A2,), (value A3), ...)

for cells in ws.iter_rows(min_row=2, 
                          min_col=min_col, max_col=min_col,
                          values_only=True):
    value = cells[0]

    # Condition, which to count
    if value is not None:
        val_counter += 1

print('Values are {}'.format(val_counter))
# >>> Values are 2

Решение ООП :

Расширение openpyxl class Worksheet с помощью метода .filter(....

import openpyxl

class Worksheet:
    def __init__(self, pyxl):
        for attr in ['filter', 'filter_list']:
            setattr(pyxl.worksheet.worksheet.Worksheet, 
                    attr, 
                    getattr(Worksheet, attr)
                   )

    def filter(self, f, range=None, values_only=True):
        cells = self.iter_rows(min_row=range[0],
                               min_col=range[1],
                               max_row=range[2],
                               max_col=range[3],
                               values_only=values_only
                              )

        for row in cells: 
            yield from (c for c in row if f(c))

    def filter_list(self, f, range=None, values_only=True):
        return [v for v in self.filter(f, range, values_only)]

# Extend openpyxl Worksheet
Worksheet(openpyxl)

Использование :

wb = openpyxl.Workbook()
ws = wb.active

# Add some test data
ws.append(['Title', 'Title', 'Title'])
for r in range(3):
    if r == 1:
        ws.append([None, None, None])
    else:
        ws.append([1, 3, 4])


# Filter Values, where Cell.value is not None
# range(min_row, min_col, max_row, max_col)
# Return a List of Values
cells = ws.filter_list(lambda v: v is not None, 
                       range=(2, 1, ws.max_row, 1)

print('Values are {}'.format(len(cells)))
# >>> Values are 2
0 голосов
/ 25 октября 2019

Электронные таблицы - это таблицы строк и столбцов, поэтому, если электронная таблица имеет 30 строк, все столбцы имеют 30 ячеек. Что касается того, активна ли ячейка или нет, вы должны решить, каковы критерии для этого, но это тривиально:

not_empty = [c for c in ws.iter_rows(min_col=1, max_col=1, values_only=True) if c[0] is not None]
print(len(not_empty))
...