Pandas Эквивалент Excel Sumifs

У меня есть фрейм данных, который представляет собой таблицу единиц с соответствующими датами начала, типами и мощностями.

Я создал второй кадр данных, который представляет собой временной ряд совокупной емкости единиц с двумя столбцами типов, стандартных и экзотических.

У меня возникли проблемы с использованием python для расчета совокупной емкости стандартных и экзотических столбцов по дате в таблице временных рядов. Как лучше всего это сделать?

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

=sumifs(capacity table['capacity' range], capacity table['start date' range],"<=" time series['date'],capacity table['type' range],"Standard")

=sumifs(capacity table['capacity' range], capacity table['start date' range],"<=" time series['date'],capacity table['type' range],"Exotic")

Таблица емкости

Unit Start Date Type Capacity
A 01/01/2021 Standard 10
B 01/03/2021 Standard 10
C 01/04/2021 Standard 10
D 01/05/2021 Exotic 15
E 01/07/2021 Exotic 15
F 01/09/2021 Exotic 15
G 01/10/2021 Exotic 15

Временная последовательность

Date Standard Cap Exotic Cap
01/01/2021 10 0
01/02/2021 10 0
01/03/2021 20 0
01/04/2021 30 0
01/05/2021 30 15
01/06/2021 30 15
01/07/2021 30 35
01/08/2021 30 30
01/09/2021 30 45
01/10/2021 30 60

person BlakeCrest1    schedule 15.03.2021    source источник
comment
В Time Series должно ли Exotic Cap на 01/07/2021 быть 30 вместо 35?   -  person tdy    schedule 15.03.2021
comment
Ты прав. Должно быть 30. Извините за опечатку.   -  person BlakeCrest1    schedule 16.03.2021


Ответы (2)


Исходя из таблицы мощностей:

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

df['Start Date'] = pd.to_datetime(df['Start Date'])

df['Standard Cap'] = df.apply(lambda row: row['Capacity'] if row['Type'] == 'Standard' else 0,
    axis=1)
df['Exotic Cap'] = df.apply(lambda row: row['Capacity'] if row['Type'] == 'Exotic' else 0,
    axis=1)

df1 = pd.DataFrame({'Date':pd.date_range(start=df.iloc[0,1], end=df.iloc[-1,1])})

df1 = df1.merge(df, how = 'left', left_on = 'Date', right_on = 'Start Date')

df1.drop(['Unit', 'Start Date', 'Type', 'Capacity'], inplace = True, axis=1)

df1.fillna(0, inplace = True)

df1['S_Cap_Cumulative'] = df1['Standard Cap'].cumsum()
df1['E_Cap_Cumulative'] = df1['Exotic Cap'].cumsum()

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

Также можно удалить столбцы Standard и Exotic Cap с помощью:

df1.drop(['Standard Cap', 'Exotic Cap'], inplace = True, axis=1)
person jojo_040    schedule 15.03.2021
comment
Спасибо, jojo_040. Я ценю вашу помощь. - person BlakeCrest1; 16.03.2021
comment
Нет проблем BlakeCrest1 (проголосовать за решение было бы любезно/полезно ;P ) - person jojo_040; 16.03.2021

Вы можете pivot в желаемый макет Time Series возьмите cumsum, а затем преобразуйте его в ежедневный индекс времени с помощью asfreq('D'):

df = (df.pivot_table(index='Start Date', columns='Type', values='Capacity')
        .cumsum()
        .asfreq('D').ffill().fillna(0))
Start Date Exotic Standard
2021-01-01 0.0 10.0
2021-01-02 0.0 10.0
2021-01-03 0.0 20.0
2021-01-04 0.0 30.0
2021-01-05 15.0 30.0
2021-01-06 15.0 30.0
2021-01-07 30.0 30.0
2021-01-08 30.0 30.0
2021-01-09 45.0 30.0
2021-01-10 60.0 30.0

Минимальный воспроизводимый пример:

import pandas as pd
import numpy as np
df = pd.DataFrame({
    'Start Date': ['01/01/2021', '01/03/2021', '01-04-2021', '01/05/2021', '01/07/2021', '01/09/2021', '01/10/2021'],
    'Type': ['Standard']*3 + ['Exotic']*4,
    'Capacity': [10]*3 + [15]*4,
}).set_index('Start Date')
df.index = pd.to_datetime(df.index)
df = df.pivot_table(index='Start Date', columns='Type', values='Cumulative').cumsum()
df = df.asfreq('D').ffill().fillna(0)
person tdy    schedule 15.03.2021
comment
tdy, большое спасибо за помощь. - person BlakeCrest1; 16.03.2021