Я написал функцию, которая создает таблицу периодов, учитывая сравнение значения из ряда, а также определенную минимальную продолжительность.
Теперь я недавно очистил свою среду, и почему-то та же функция больше не присваивает значения, как раньше. Однако он по-прежнему создает фрейм данных правильной формы, просто не присваивает значения, и я не могу понять, почему.
Предыдущий вывод:
Текущий выход:
from datetime import datetime
import pandas as pd
pd.options.mode.chained_assignment = None
import pandas_datareader.data as web
import dataframe_image as dfi
# getting the last periods of increasing interest rates (Federal Funds Effective MONTHLY Rate) from 1965 onwards
fed_rates = web.DataReader("FEDFUNDS", "fred", 1965)
fed_rates.set_index(pd.to_datetime(fed_rates.index.date), inplace=True)
# test for empty values
print(fed_rates.index.isna().sum())
def period_df(start, duration, fed_rates=fed_rates):
fed_rates = fed_rates[fed_rates.index >= start]
df = pd.DataFrame(columns=["Name", "Start", "Last"])
df.loc[df.shape[0]] = [None, None, None]
period = 0
j = 0
for i in range(0, len(fed_rates) - 1):
if (fed_rates.iloc[i + 1]["FEDFUNDS"] <= fed_rates.iloc[i]["FEDFUNDS"]) and (
i - j >= duration
):
df.loc[period]["Last"] = datetime.strftime(fed_rates.index[i], "%Y-%m-%d")
period += 1
if (fed_rates.index[-1] - fed_rates.index[i]).days >= 365:
df.loc[len(df)] = [None, None, None]
j = i
elif (fed_rates.iloc[i + 1]["FEDFUNDS"] <= fed_rates.iloc[i]["FEDFUNDS"]) and (
i - j < duration
):
df.iloc[period]["Name"] = "Period " + str(period + 1)
df.loc[period]["Start"] = datetime.strftime(fed_rates.index[i], "%Y-%m-%d")
j = i
# add last date
df.loc[period]["Last"] = datetime.strftime(fed_rates.index[-1], "%Y-%m-%d")
# add duration column
df["Duration"] = (
pd.to_datetime(df["Last"]) - pd.to_datetime(df["Start"])
) / np.timedelta64(1, "M")
# export df as image
dfi.export(
df.style.set_properties(
**{"background-color": "white", "color": "black", "border-color": "#948b8b"}
),
"periods" + start + ".png",
)
return df
period_df(start = "1995", duration=9)
Да, но раньше это не было проблемой. Нужно ли мне возвращать панды к какой-то другой версии?
Что ж, это странно. Но я считаю, что причиной вашей проблемы сейчас являются ваши df.loc[row][col] (или iloc) задания. Когда вы делаете это таким образом, df.loc[row] выполняется первым и возвращает копию строки, поэтому любые изменения вносятся в копию, а не в исходные данные. Попробуйте использовать df.loc[row, col] или df.at[row, col] для заданий и посмотрите, поможет ли это.
Это фактически исправило это. Так просто, спасибо. Но также странно, что это работало раньше
Да, определенно странно. Я опубликую ответ для справки.






В пандах операции loc/iloc, когда они ничего не устанавливают, просто возвращают копию данных.
Когда вы делаете что-то вроде df.loc[row][col] = value, это может выглядеть как установка операции loc, но это «назначение» происходит в два этапа:
df.loc[row] извлекает копию соответствующей строкиcol устанавливается на valueВы можете избежать этого, передав row и col в loc/iloc или даже используя at/iat:
df.loc[row, col] = value
df.at[row, col] = value
Вы получаете предупреждение с именем
SettingWithCopyWarningпри запуске кода?