Pandas Функция суммы данных с различными критериями столбца - PullRequest
1 голос
/ 09 января 2020

Эта функция суммирует строки в фрейме данных на основе 5 различных критериев (начальная дата, конечная дата, фонд, счет и анализ):

df = pd.DataFrame(
    [
    ['02-09-2019',20190902,  20.00,  'F1','B1','I2'],
    ['23-09-2019',20190923,  237.36, 'F1','B1','I1'],
    ['15-11-2019',20191115,  200.00, 'F1','B1','I1'],
    ['16-11-2019',20191116,  2045.00, 'F1','B1','I2'],
    ['05-05-2020',20200505,  205.00, 'F2','B2','I1'],
    ],
    columns= ['Datestr','Datenum','Cost','Fund','Account','Analysis'])


def per_sum(startdate, enddate, fund, account, analysis):
    return df[(df.Datenum > startdate) &
              (df.Datenum < enddate) &
              (df.Fund == fund) &
              (df.Account == account) &
              (df.Analysis == analysis)
              ].Cost.sum()


per_sum(20190000,20200000,'F1','B1','I1')

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

Например: если я хотел найти общий анализ «I2» (во всех фондах и счетах).

Подобные вещи не работают:

per_sum(20190000,20200000,'','','I2')

Спасибо

Ответы [ 3 ]

2 голосов
/ 09 января 2020

Идея является цепочкой по | для bitwise OR нового решения для сравнения по пробелам:

def per_sum(startdate, enddate, fund, account, analysis):
    return df[(df.Datenum > startdate) &
              (df.Datenum < enddate) &
              ((df.Fund == fund) | (fund == '')) &
              ((df.Account == account) | (account == '')) &
              ((df.Analysis == analysis) | (analysis == ''))
              ].Cost.sum()

print(per_sum(20190000,20200000,'','',''))
2502.36

print(per_sum(20190000,20200000,'','','I2'))
2065.0

РЕДАКТИРОВАТЬ:

Если хотите также фильтр с датами, добавьте одно возможное решение if-else оператор для начальной и конечной даты chnage:

def per_sum(startdate, enddate, fund, account, analysis):
    startdate = -np.inf if startdate == '' else startdate
    enddate = np.inf if enddate == '' else enddate
    return df[(df.Datenum > startdate) &
              (df.Datenum < enddate) &
              ((df.Fund == fund) | (fund == '')) &
              ((df.Account == account) | (account == '')) &
              ((df.Analysis == analysis) | (analysis == ''))
              ].Cost.sum()

print(per_sum('','','','',''))
2707.36
1 голос
/ 09 января 2020

Это может быть не очень элегантно, но прозрачно и надежно:

def per_sum_2(startdate, enddate, fund = None, account=None, analysis=None):

    df2 = df[(df.Datenum > startdate) &
              (df.Datenum < enddate) ]
    if not fund is None:
        df2 = df2[df2.Fund == fund]
    if not account is None:
        df2 = df2[df2.Account == account]
    if not analysis is None:
        df2 = df2[df2.Analysis == analysis]

    return df2.Cost.sum()

per_sum_2(20190000,20200000,analysis='I2')

2065.0
0 голосов
/ 09 января 2020

Это:

per_sum(20190000,20200000,'','','I2') 

не работает, потому что '' не является подстановочным знаком, подходящим для всех случаев / значений для этого столбца. Вы можете использовать выражения регулярных выражений для сопоставления всех значений для значений столбцов.

Вы можете изменить объявление функции, чтобы оно содержало значения по умолчанию для столбцов, поэтому, если вы хотите игнорировать одно из них, вы # не даете ему параметр при вызове функции.

def per_sum(startdate, enddate, fund='somepattern', account='otherpattern', analysis):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...