Разбор в Dataframe для каждой строки

Я хочу выполнить расчет, согласно которому для каждой конечной даты письма нужно минус с 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

Есть ли какие-либо другие советы, чтобы выполнить это и получить общее количество на основе значений каждой строки?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь нет необходимости использовать цикл 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 ?

orkedahmad 17.03.2022 13:41

Другие вопросы по теме