кадр данных перезаписывается при использовании понимания списка - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь создать четыре новых pandas кадра данных с использованием списка. Каждый новый фрейм данных должен быть оригинальным фреймом данных «конституция_состава» с двумя новыми столбцами. Эти два столбца добавляют определенное количество лет к существующему столбцу и возвращают значение. Пример кода ниже

def add_maturity(df, tenor):
    df['tenor'] = str(tenor) + 'Y'
    df['maturity'] = df['effectivedate'] + pd.DateOffset(years=tenor)
    return df

year_list = [3, 5, 7, 10]
new_dfs = [add_maturity(constituents_file, tenor) for tenor in year_list]

Мой ожидаемый вывод в списке new_dfs должен иметь четыре кадра данных, каждый из которых имеет различное значение для tenor и maturity. В моих результатах все четыре фрейма данных имеют одинаковые данные с тенором 10Y и сроком погашения, который на 10 лет больше, чем в столбце «дата действия».

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

Большое спасибо

1 Ответ

1 голос
/ 20 февраля 2020

Когда вы присваиваете объекту DataFrame, вы вносите изменения на месте. И когда вы передаете его в качестве аргумента функции, вы передаете ссылку на объект DataFrame, в данном случае ссылку на один и тот же объект DataFrame каждый раз, так что это перезаписывает предыдущие результаты. .

Чтобы решить эту проблему, вы можете либо создать копию DataFrame в начале функции:

def add_maturity(df, tenor):
    df = df.copy()
    df['tenor'] = str(tenor) + 'Y'
    df['maturity'] = df['effectivedate'] + pd.DateOffset(years=tenor)
    return df

(Или вы можете оставить функцию как есть, и иметь caller сначала скопируйте DataFrame при передаче его в качестве аргумента ...)

Или вы можете использовать метод assign(), который возвращает новый DataFrame с измененными столбцами:

def add_maturity(df, tenor):
    return df.assign(
        tenor= str(tenor) + 'Y',
        maturity=df['effectivedate'] + pd.DateOffset(years=tenor),
    )

(Лично я бы go с последним. Это похоже на то, как работает большинство методов DataFrame, в том, что они обычно возвращают новый DataFrame, а не изменяют его на месте.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...