Openpyxl сравнить клетки - PullRequest
       16

Openpyxl сравнить клетки

0 голосов
/ 11 декабря 2018

У меня есть 2 листа с некоторыми данными (по 18 тыс. Строк), и мне нужно проверить, существует ли значение из source.xlsx в файле target.xlsx.Строки в исходном файле должны быть уникальными.Если ячейка из исходного файла существует в целевом файле (в определенном столбце), то в следующем столбце в целевом файле необходимо заполнить значение из некоторого столбца, который находится в исходном файле.Это довольно сложно, поэтому пример будет выглядеть так:

target.xlsx

<table><tbody><tr><th>Data</th><th>price</th><th> </th></tr><tr><td>1234grt   </td><td> </td><td> </td></tr><tr><td>7686tyug  </td><td> </td><td> </td></tr><tr><td>9797tyu   </td><td>   </td><td> </td></tr><tr><td>9866yyy   </td><td> </td><td> </td></tr><tr><td>98845r  </td><td> </td><td> </td></tr><tr><td>4567yut  </td><td> </td><td> </td></tr><tr><td>1234grt</td><td> </td><td> </td></tr><tr><td>98845r </td><td> </td><td> </td></tr></tbody></table>

source.xls

<table><tbody><tr><th>Data</th><th>price</th><th> </th></tr><tr><td>98845r    </td><td>$50</td><td> </td></tr><tr><td>7686tyug  </td><td>$67</td><td> </td></tr><tr><td>9797tyu   </td><td>$56</td><td> </td></tr><tr><td>4567yut   </td><td>$67</td><td> </td></tr><tr><td>9866yyy   </td><td>$76</td><td> </td></tr><tr><td>98845r    </td><td>$56</td><td> </td></tr><tr><td>1234grt</td><td>$34</td><td> </td></tr></tbody></table>

for i in range(1, source_sheet_max_rows, 1):
print(i)
if source_wb[temp_sheet_name].cell(row=i, column=1).value in target_values:
    for j in range(1, target_sheet_max_rows, 1):
        if target_wb[temp_sheet_name].cell(row=j, column=1).value == source_wb[temp_sheet_name].cell(row=i,
                                                                                                           column=1).value:
            target_wb[temp_sheet_name].cell(row=j, column=2).value = source_wb[temp_sheet_name].cell(row=i,
                                                                                                             column=2).value
            target_wb.save(str(temp_sheet_name))

target_values ​​- содержит значения из столбца 1 целевого листа

Приведенный выше код работает, но очень тяжелый, и я думаю,есть лучший способ сделать это.Файлы содержат более 18 тыс. Строк, поэтому для сравнения данных понадобится много времени.Сложность в том, что мне нужно знать, в какой строке в целевом файле моя ячейка из исходного файла должна заполнить столбец соответствующим значением.Я использую openpyxl, но если бы это было проще, я мог бы использовать панд.

Thx

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Вопрос : проверьте, существует ли значение из source.xlsx в файле target.xlsx.

Реализуйте его, как в следующем примере:
Документация: OpenPyXl - accessing-many-cell
Python - Типы отображения - dict , Python - объект .__ init __

class SourceSheet:
    def __init__(self, ws):
        self.ws = ws

    def __iter__(self):
        """
        Implement iterRows or iterRange
        :return: yield a tuple (value_to_search, value_to_fill)
        """
        # Example iterRange
        for row in range(1, self.ws.max_rows + 1):
            yield (self.ws.cell(row=row, column=1).value, self.ws.cell(row=row, column=2).value)

class TargetSheet:
    def __init__(self, ws):
        self.ws = ws

        """
        Create a 'dict' from all Values in Column A
        This allows Random Access the Cell Value to get the Cell Row Index
        Dict.key == Cell Value
        Dict.value = Cell Row Index
        _columnA = {} # {cell.value:cell.row}
        """
        self._columnA = dict(((c.value, c.row) for c in ws['A']))

    def find(self, value):
        """
        Implement either linear Search using iterRows over one Column or
                         search in dict to find 'value'
        :param value: The value to find
        :return: The Cell, to write the 'value_to_fill'
        """
        # Example using dict
        if value in self._columnA:
            return self.ws.cell(row=self._columnA[value], column=2)


sourceSheet = SourceSheet(ws1)
targetSheet = TargetSheet(ws2)        

for value_to_search, value_to_fill in sourceSheet:
    print("SourceSheet:{}".format((value_to_search, value_to_fill)))
    targetCell = targetSheet.find(value_to_search)

    if targetCell:
        print("Match: Write value '{}' to TargetSheet:'{}'".format(value_to_fill, targetCell))
        targetCell.value = value_to_fill
    else:
        print("Value '{}' not fount in TargetSheet!".format(value_to_search))

Выход :

SourceSheet:('cell.A1.value', 'cell.B1.value')
Match: Write value 'cell.B1.value' to TargetSheet:'Cell.B1:'
SourceSheet:('cell.A2.value', 'cell.B2.value')
Match: Write value 'cell.B2.value' to TargetSheet:'Cell.B2:'
SourceSheet:('cell.A3.value', 'cell.B3.value')
Match: Write value 'cell.B3.value' to TargetSheet:'Cell.B3:'

Проверено на Python: 3,5

0 голосов
/ 11 декабря 2018

Из моего понимания вашего вопроса кажется, что строки в целевом файле расположены не в том же порядке, что и исходный файл.

for i in range(1, souce_sheet_max_rows):
    for j in range(1, target_sheet_max_rows):
        if target_wb[temp_sheet_name].cell(row=j, column=1).value == source_wb[temp_sheet_name].cell(row=i, column=1).value:
            target_wb[temp_sheet_name].cell(row=j, column=2).value == source_wb[temp_sheet_name].cell(row=i, column=2).value
            break
target_wb.save(temp_sheet_name)
...