Условная кумулятивная сумма нескольких строк в кадре данных - PullRequest
0 голосов
/ 03 ноября 2018

Я пытаюсь найти кумулятивную сумму для четырех последовательных строк в кадре данных на основе условия.

Новый столбец ( 'veh_time_TOT' ) представляет собой сумму четырех последовательных значений ' veh_time (s) ' и условие ' Day_type ': Выходные или будний день.

Вот как теперь настраиваются данные:

    veh-time(s) distance(m) Day_type
0   72  379.0   Weekday
1   70  379.0   Weekday
2   50  379.0   Weekday
3   60  379.0   Weekday
4   70  379.0   Weekday
5   65  379.0   Weekday
6   30  379.0   Weekend
7   35  379.0   Weekend
8   30  379.0   Weekend
9   30  379.0   Weekend
10  20  379.0   Weekend 

Вот желаемый вывод:

    veh-time(s) distance(m) Day_type    veh_time_TOT
0   72  379.0   Weekday        0
1   70  379.0   Weekday        0
2   50  379.0   Weekday        0
3   60  379.0   Weekday        252
4   70  379.0   Weekday        250
5   65  379.0   Weekday        245
6   30  379.0   Weekend        0
7   35  379.0   Weekend        0
8   30  379.0   Weekend        0
9   30  379.0   Weekend        125
10  20  379.0   Weekend        115  

Я пробовал несколько вещей, но единственное, что я мог найти, это использовать функцию .cumsum, которая находит сумму только для 2 последовательных строк. Нули в " veh_time_TOT " есть, потому что еще не было 4 строк, чтобы составить сумму.

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

Что вы, ребята, думаете? Любая помощь приветствуется.

1 Ответ

0 голосов
/ 04 ноября 2018

Вот шаги, которые я предпринял, чтобы получить нужный столбец:

  • Сначала я настроил ваш пример DataFrame.

  • Далее я определил три интересующих столбца (столбец которого значения будут основой расчета, столбец используется для сравнение, и имя столбца для рассчитанного количества.

  • После этого я нахожу все строки, подходящие для этого вычисления (предыдущие 4 строки имеют одинаковое значение для col_compare).
  • Затем я перебираю этот фрагмент исходного DataFrame, суммируя предыдущие четыре значения col_val.

  • Наконец, я создаю новый столбец с желаемым именем col_name_new

    • Инициализировать его значения в ноль
    • Заполните подходящие местоположения списком, который мы создали на предыдущем шаге:

Вот мой код, не стесняйтесь задавать вопросы в комментариях!

import pandas as pd

# Setup

cols = ['veh-time(s)', 'distance(m)', 'Day_type']

data= [[72,  379.0 ,  'Weekday'],
       [70,  379.0 ,  'Weekday'],
       [50,  379.0 ,  'Weekday'],
       [60,  379.0 ,  'Weekday'],
       [70,  379.0 ,  'Weekday'],
       [65,  379.0 ,  'Weekday'],
       [30,  379.0 ,  'Weekend'],
       [35,  379.0 ,  'Weekend'],
       [30,  379.0 ,  'Weekend'],
       [30,  379.0 ,  'Weekend'],
       [20,  379.0 ,  'Weekend']]


df = pd.DataFrame(data,columns=cols )

# Define columns for potential future generalization

col_val='veh-time(s)'
col_compare='Day_type'
col_name_new = 'veh_time_TOT'

# DataFrame slice of rows eligible for calculation

cut_prev_four =  (df[col_compare].shift(1)==df[col_compare]) \
                &(df[col_compare].shift(2)==df[col_compare].shift(1)) \
                &(df[col_compare].shift(3)==df[col_compare].shift(2))

df_consecutive = df[cut_prev_four]

# Perform calculation on eligible rows. Store in list

prev_four_list = []
for i,row in df_consecutive.iterrows():
    prev_four_vals = df.iloc[i-3:i+1][col_val].values
    print(i, prev_four_vals, sum(prev_four_vals) )
    prev_four_list.append(sum(prev_four_vals))

# Set new column to the calculated values

df[col_name_new] = 0
df.loc[cut_prev_four, col_name_new] = prev_four_list
...