обработать фрейм данных, извлеченный из SQL с помощью pandas, и составить список - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь взять pandas фрейм данных, полученный от SQL, отфильтровать местоположения (код измерения размера 1) и рассчитать сумму - кредиты для каждого.

Приведенный ниже код дает мне следующая ошибка:

ValueError: Значение истинности Серии неоднозначно. Используйте a.empty, a.bool (), a.item (), a.any () или a.all ()

. Буду признателен за любой совет или помощь в его работе: |

inv = inv_line_query()
crmemo = cr_memo_line_query()


def mtd_actual(invoices=inv, creds=crmemo, location=['*']):
    mtd_actual_dict = {}
    invoices = invoices[invoices['Shortcut Dimension 1 Code'].isin(location)]
    creds = creds[creds['Shortcut Dimension 1 Code'].isin(location)]
    for loc in location:
        amt = [round(x, 2) for x in invoices['Amount'] if invoices['Shortcut Dimension 1 Code'] == loc]
        cred = [round(x, 2) for x in creds['Amount'] if creds['Shortcut Dimension 1 Code'] == loc]
        mtd_actual_dict[loc] = round(sum(amt) - sum(cred), 2)
    return mtd_actual_dict


print(mtd_actual(inv, crmemo, ['AB', 'BC', 'ONT']))

Ответы [ 3 ]

1 голос
/ 21 февраля 2020

Dataframe работает в столбчатой ​​структуре, поэтому для вычисления l oop при вычислении amt и cred невозможно выполнить итерацию так, как вы упомянули.

Изменение кода, подобного этому, сработает легко.

inv = inv_line_query()
crmemo = cr_memo_line_query()

def mtd_actual(invoices=inv, creds=crmemo, location=None):
    mtd_actual_dict = {}
    invoices = invoices[invoices['Shortcut Dimension 1 Code'].isin(location)]
    creds = creds[creds['Shortcut Dimension 1 Code'].isin(location)]
    for loc in location:
        amt = invoices[invoices['Shortcut Dimension 1 Code'] == loc]['Amount'].sum()
        cred = creds[creds['Shortcut Dimension 1 Code'] == loc]['Amount'].sum()
        mtd_actual_dict[loc] = round((amt - cred), 2)
    return mtd_actual_dict


print(mtd_actual(inv, crmemo, ['AB', 'BC', 'ONT']))

Кроме того, похоже, что вам нужны значения, основанные на местоположении в словаре. Вместо итерации по местоположению вы также можете использовать функции pandas Dataframe. Это решение будет эффективно масштабироваться в большом списке местоположений, тогда как предыдущее решение может вызвать вычислительные затраты.

def mtd_actual(invoices=inv, creds=crmemo, location=None):
    # filter values based on location
    invoices = invoices[invoices['Shortcut Dimension 1 Code'].isin(location)]
    creds = creds[creds['Shortcut Dimension 1 Code'].isin(location)]

    # group on location and sum the amount
    inv_grp = invoices.groupby('Shortcut Dimension 1 Code').agg({"Amount" : "sum"}).reset_index()
    cred_grp = creds.groupby('Shortcut Dimension 1 Code').agg({"Amount" : "sum"}).reset_index()

    # merge these two dataframes, make sure this needs to be an outer join
    final = inv_grp.merge(cred_grp, 
                          on='Shortcut Dimension 1 Code', 
                          suffix=("", "_"),
                          how="outer")

    # fill nan values with 0
    final[["Amount", "Amount_"]] = final[["Amount", "Amount_"]].fillna(0)
    final["diff"] = round(final['Amount'] - final['Amount_'], 2)

    return final[["Shortcut Dimension 1 Code", "diff"]].to_dict("record")
1 голос
/ 21 февраля 2020

Вы выставляете счета-фактуры ['Сокращенный код измерения 1']. Isin (местоположение) и кредиты ['Сокращенный код измерения 1']. Isin (местоположение), которые являются списком логических значений для фильтрации данных, но для фильтрации вы должны предоставить список индексов, а не список логических значений.

Я бы попытался преобразовать эти списки в индекс информационного кадра, примерно так:

изменив эту часть в вашем коде:

 invoices = invoices[invoices['Shortcut Dimension 1 Code'].isin(location)]
 creds = creds[creds['Shortcut Dimension 1 Code'].isin(location)]

к этому:

    list_of_bools_invoices = invoices['Shortcut Dimension 1 Code'].isin(location)
    list_of_index_invoices = [index_of_row for index_of_row,bool in enumerate(list_of_bools_invoices) if bool]
    invoices = invoices[list_of_index_invoices]

    list_of_bools_creds = creds['Shortcut Dimension 1 Code'].isin(location)
    list_of_index_creds = [index_of_row for index_of_row,bool in enumerate(list_of_bools_creds) if bool]
    creds = creds[list_of_index_creds]
0 голосов
/ 21 февраля 2020

Рассмотрим обработку вычислений с помощью pandas Операции серии:

...
    amt = invoices[invoices['Shortcut Dimension 1 Code'] == loc]['Amount'].round(2) 
    cred = creds[creds['Shortcut Dimension 1 Code'] == loc]['Amount'].round(2)

    mtd_actual_dict[loc] = (amt.sum() - cred.sum()).round(2)
return mtd_actual_dict
...