Polars, iter_rows, Цикл for пропускает часть строк

Есть входные данные (движение по складу). Задача под каждый документ подобрать "документ покупки" и посчитать остаток на каждом "документе покупки". Единственный метод, который я нашла: фильтр всех строк по коду продукта, потом перебор каждой строки. Все в принципе работает, кроме приведенного примера. Продали все, т.е. Remains = 0. Но после этого происходит корректировка документа продажи и возврат продукта на склад, после чего он списывается. Мой код останавливается и пропускает последние 2 документа (корректировку и списание). По итогу они теряются в принципе.

введите сюда описание изображения

Код выложила на Git, потому что длинный цикл получился -> ссылка на код

import polars as pl

data = {
    "Doc_N": ['00ОП-000157', '00ОП-002240', '00ОП-001840', '00ОП-000216', '00ОП-000029', ],
    "Doc_date": ['27.02.2023', '21.11.2023', '17.04.2024', '01.10.2024', '01.10.2024', ],
    "Prod_code": ['ОП-0001201', 'ОП-0001201', 'ОП-0001201', 'ОП-0001201', 'ОП-0001201', ],
    "Doc_type": ['income', 'outcome', 'outcome', 'outcome', 'outcome', ],
    "Doc_type2": ['purchase', 'sale', 'sale', 'correction', 'writeoff', ],
    "Qty": [32, -3, -29, 29, -29, ]
}

main_df = pl.DataFrame(data)
main_df = main_df.with_columns(pl.col("Doc_date").str.to_date('%d.%m.%Y'), pl.col("Qty").cast(pl.Float64, strict=False))

codes = main_df[["Prod_code"]]
codes = codes.unique(subset=['Prod_code'])

results = []

for code in codes.iter_rows(named=True):
    new_df = main_df.filter(pl.col("Prod_code") == code["Prod_code"])
    new_df = new_df.sort("Doc_date", "Doc_type", "Doc_N", "Qty", descending=[False, False, False, False])
    new_df = new_df.with_row_index(name="my_index", offset=1)
    max_row = len(new_df)
    
    for row in new_df.iter_rows(named=True):
        document = row["Doc_N"]
        date = row["Doc_date"]
        incom_code = row["Prod_code"]
        quantity = row["Qty"]
        if row["Doc_type"] != 'income':
            matched_documents = []
            remaining_qty = abs(quantity)

            for prev_row in results:
                if (prev_row["Prod_code"] == incom_code
                    and prev_row.get("Remains", 0) > 0
                    # and ( (prev_row.get("Remains", 0) > 0) or (prev_row.get("Remains", 0) == None))
                    # and prev_row.get("my_index") < (prev_row["my_index"])
                    and prev_row["Doc_date"] <= date ):
                    available_qty = prev_row["Remains"]
                    take_qty = min(remaining_qty, available_qty)
                        
                    if quantity > 0:
                        prev_row["Remains"] += take_qty
                    else:
                        prev_row["Remains"] -= take_qty

                    if (row["Doc_type2"] == "complectation") or (row["Doc_type2"] == "writeoff"):
                        matched_documents.append({
                            "Inc_Doc": prev_row["Doc_N"],
                            "Inc_Doc_date": prev_row["Doc_date"],
                            "Inc_Doc_code": incom_code,
                            "Qty": -take_qty if quantity < 0 else take_qty,
                            'available_qty': available_qty,
                            'take_qty': take_qty,
                            'prev_row["Remains"]': prev_row["Remains"],
                            "my_index": row["my_index"]
                            })
                    else:
                        matched_documents.append({
                            "Inc_Doc": prev_row["Doc_N"],
                            "Inc_Doc_date": prev_row["Doc_date"],
                            "Inc_Doc_code": "",
                            "Qty": -take_qty if quantity < 0 else take_qty,
                            'available_qty': available_qty,
                            'take_qty': take_qty,
                            'prev_row["Remains"]': prev_row["Remains"],
                            "my_index": row["my_index"]
                            })
                        
                    remaining_qty -= take_qty

                    if int(row["my_index"]) == max_row:
                        break

                    
            for matched_doc in matched_documents:
                results.append({
                    "Doc_N": document,
                    "Doc_date": date,
                    "Doc_type2": row['Doc_type2'],
                    "Inc_Doc": matched_doc["Inc_Doc"],
                    "Inc_Doc_date": matched_doc["Inc_Doc_date"],
                    "Prod_code": incom_code,
                    'Qty': matched_doc['Qty'],
                    "Inc_Doc_code": matched_doc["Inc_Doc_code"],
                    'available_qty': matched_doc['available_qty'],
                    'take_qty': matched_doc['take_qty'],
                    'prev_row["Remains"]': matched_doc['prev_row["Remains"]'],
                    "my_index": matched_doc["my_index"]
                })
        else:
            results.append({
                "Doc_N": document,
                "Doc_date": date,
                "Doc_type2": row['Doc_type2'],
                "Prod_code": incom_code,
                'Qty': row['Qty'],
                "Remains": quantity,
                "my_index": row["my_index"]
            })

result_df = pl.DataFrame(results)

Ответы (0 шт):