Я хочу выполнить расчет, согласно которому для каждой конечной даты письма нужно минус с Start_Date,
, а затем разделить на 365, чтобы получить продолжительность в годах. Затем продолжительность каждого столбца букв необходимо использовать как «степень» значения их столбца букв соответственно. Затем результат каждой буквы необходимо суммировать, чтобы получить общее количество.
Я пробовал использовать код ниже, где я использую синтаксический анализ, и мне удалось получить ответ.
import pandas as pd
dataset = [['01-01-2015', 234, '25-05-2017', 633, '03-06-2016', 935, '30-10-2019', 673, '16-12-2020', 825, '06-07-2019'],
['01-01-2015', 664, '25-05-2017', 663, '03-06-2016', 665, '30-10-2019', 663, '16-12-2020', 665, '06-07-2019']]
ds = pd.DataFrame(dataset, columns = ['Start_Date', 'A', 'End_Date_A', 'B', 'End_Date_B', 'C', 'End_Date_C',
'D', 'End_Date_D', 'E', 'End_Date_E'])
Start_Date A End_Date_A B End_Date_B C End_Date_C D End_Date_D E End_Date_E
0 01-01-2015 234 25-05-2017 633 03-06-2016 935 30-10-2019 673 16-12-2020 825 06-07-2019
1 01-01-2015 664 25-05-2017 663 03-06-2016 665 30-10-2019 663 16-12-2020 665 06-07-2019
from dateutil import parser
import math
letters = ["A", "B", "C", "D", "E"]
total = 0
for i in ds.index:
for letter in letters:
start_date = parser.parse(ds["Start_Date"][i])
end_date = parser.parse(ds["End_Date_" + letter][i])
years = (end_date - start_date).days / 365
power = math.pow(int(ds[letter][i]), years)
total+= power
ds['Overall'] = total
Однако он показывает один и тот же результат для каждой из строк.
Start_Date A End_Date_A B End_Date_B C End_Date_C D End_Date_D E End_Date_E Overall
0 01-01-2015 234 25-05-2017 633 03-06-2016 935 30-10-2019 673 16-12-2020 825 06-07-2019 1.388585e+17
1 01-01-2015 664 25-05-2017 663 03-06-2016 665 30-10-2019 663 16-12-2020 665 06-07-2019 1.388585e+17
Есть ли какие-либо другие советы, чтобы выполнить это и получить общее количество на основе значений каждой строки?
Здесь нет необходимости использовать цикл for, мы можем использовать подход, основанный на векторных пандах.:
letters = pd.Index(['A', 'B', 'C', 'D', 'E'])
start = pd.to_datetime(ds['Start_Date'], dayfirst=True)
dates = ds['End_Date_' + letters].apply(pd.to_datetime, dayfirst=True)
years = dates.sub(start, axis=0).astype('timedelta64[D]').div(365)
ds['Overall'] = ds[letters].pow(years.values).sum(1)
Результат
print(ds)
Start_Date A End_Date_A B End_Date_B C End_Date_C D End_Date_D E End_Date_E Overall
0 01-01-2015 234 25-05-2017 633 03-06-2016 935 30-10-2019 673 16-12-2020 825 06-07-2019 7.261803e+16
1 01-01-2015 664 25-05-2017 663 03-06-2016 665 30-10-2019 663 16-12-2020 665 06-07-2019 6.624869e+16
Или, если вы все еще хотите использовать существующий код, вот простое решение:
for i in ds.index:
total = 0 # Moved inside outer for-loop
for letter in letters:
start_date = parser.parse(ds["Start_Date"][i])
end_date = parser.parse(ds["End_Date_" + letter][i])
years = (end_date - start_date).days / 365
power = math.pow(int(ds[letter][i]), years)
total+= power
ds.loc[i, 'Overall'] = total # Notice the change here
благодарю вас. это действительно работает! Однако я пытаюсь добавить новый столбец с
Rate
и хочу включить его через несколько лет, в результате чего формулаdf=1/(1+ds['Rate'])**years
. Но затем я получил сообщение об ошибкеUnable to coerce to DataFrame, shape must be (2, 4): given (2, 6)
. Как мне исправитьdf
?