Python Pandas: как вставить новый столбец, который представляет собой сумму следующих «n» (также может быть дробью) значений другого столбца?

У меня есть DataFrame, скажем, имя «тест», хранящее данные, как показано ниже:

   Week  Stock(In Number of Weeks)  Demand (In Units)
0   W01                        2.4                 37
1   W02                        3.6                 33
2   W03                        2.0                 46
3   W04                        5.8                 45
4   W05                        4.6                 56
5   W06                        3.0                 38
6   W07                        5.0                 45
7   W08                        7.5                 54
8   W09                        4.3                 35
9   W10                        2.2                 38
10  W11                        2.0                 50
11  W12                        6.0                 37

Я хочу вставить новый столбец в этот фрейм данных, который для каждой строки представляет собой сумму строк «Количество недель» столбца «Спрос (в единицах)».

То есть, в случае этого фрейма данных

для 0-й строки этот новый столбец должен быть суммой 2,4 строк столбца «Спрос (в единицах)», который будет равен 37 + 33 + 0,4 * 46.

для 1-й строки значение должно быть 33+46+45+ 0,6*56

для 2-го ряда должно быть 46+45

. . .

для 7-й строки должно быть 54+35+38+50+37 (поскольку количество оставшихся строк меньше значения 7,5, все оставшиеся строки суммируются)

. . . и так далее.

По сути, я хочу, чтобы у моего фрейма данных был новый столбец следующим образом:

   Week  Stock(In Number of Weeks)  Demand (In Units)  Stock (In Units)
0   W01                        2.4                 37              88.4
1   W02                        3.6                 33             157.6
2   W03                        2.0                 46              91.0
3   W04                        5.8                 45             266.0
4   W05                        4.6                 56             214.0
5   W06                        3.0                 38             137.0
6   W07                        5.0                 45             222.0
7   W08                        7.5                 54             214.0
8   W09                        4.3                 35             160.0
9   W10                        2.2                 38              95.4
10  W11                        2.0                 50              87.0
11  W12                        6.0                 37              37.0 

Может ли кто-нибудь предложить какой-то способ добиться этого?

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

for i in range(len(test)):
    if int(np.floor(test.loc[i, 'Stock(In Number of Weeks)'])) >= len(test[i:]):
        number_of_full_rows = len(test[i:])
        fraction_of_last_row = 0
        y = 0

    else:
        number_of_full_rows = int(np.floor(test.loc[i, 'Stock(In Number of Weeks)']))
        fraction_of_last_row = test.loc[i, 'Stock(In Number of Weeks)'] - number_of_full_rows
        y = test.loc[i+number_of_full_rows, 'Demand (In Units)'] * fraction_of_last_row

    x = np.sum(test[i:i+number_of_full_rows]['Demand (In Units)'])

    test.loc[i, 'Stock (In Units)'] = x+y

person Vikrant Agrawal    schedule 13.12.2019    source источник
comment
Если вы добавите код, который используете в настоящее время (с итерацией), другим будет легче понять, что именно вы ищете. И добро пожаловать в СО!   -  person ASGM    schedule 13.12.2019
comment
Привет, спасибо, @ASGM. Я включил код, который я использую прямо сейчас.   -  person Vikrant Agrawal    schedule 13.12.2019
comment
@Divakar, можешь помочь векторизовать код?   -  person Vikrant Agrawal    schedule 18.12.2019


Ответы (1)


Я попытался с некоторыми тестовыми данными:

def func(r, col):

    n = int(r['Stock(In Number of Weeks)'])
    f = float(r['Stock(In Number of Weeks)'] - n)
    i = r.name # row index value

    z = np.zeros(len(df)) #initialize all zeros
    v = np.hstack((np.ones(n), np.array(f))) # vecotor of ones and fraction part

    e = min(len(v), len(z[i:]))
    z[i:i+e] = v[:len(z[i:])] #change z starting at index until lenght

    r['Stock (In Units)'] = col @ z #compute scalar product

    return r


df = df.apply(lambda r: func(df['Demand (In Units)'].values, r), axis=1)
person FBruzzesi    schedule 13.12.2019