У меня есть следующий набор данных игрушек:
import pandas as pd
from StringIO import StringIO
# read the data
df = pd.read_csv(StringIO("""
Date Return
1/28/2009 -0.825148
1/29/2009 -0.859997
1/30/2009 0.000000
2/2/2009 -0.909546
2/3/2009 0.000000
2/4/2009 -0.899110
2/5/2009 -0.866104
2/6/2009 0.000000
2/9/2009 -0.830099
2/10/2009 -0.885111
2/11/2009 -0.878320
2/12/2009 -0.881853
2/13/2009 -0.884432
2/17/2009 -0.947781
2/18/2009 -0.966414
2/19/2009 -1.016344
2/20/2009 -1.029667
2/23/2009 -1.087432
2/24/2009 -1.050808
2/25/2009 -1.089594
2/26/2009 -1.121556
2/27/2009 -1.105873
3/2/2009 -1.205019
3/3/2009 -1.191488
3/4/2009 -1.059311
3/5/2009 -1.135962
3/6/2009 -1.147031
3/9/2009 -1.117328
3/10/2009 -1.009050"""), sep = "\s+").reset_index()
Мои цели:
а) найти самое отрицательное значение в столбце «Возврат»
б) найти дату, когда это значение произошло
c) затем «поднимитесь» по столбцу «Возврат», чтобы найти для первый случай определенное значение (в данном случае 0,000000).
г) найти дату, связанную со значением, возвращенным на шаге «с»
Результаты, которые я ищу:
а) -1,20519
б) 2 марта 2009 г.
в) 0,000000
г) 6 февраля 2009 г.
Я могу найти "а" со следующим кодом:
max_dd = df['Maximum_Drawdown'].min()
Чтобы получить «b», я попытался использовать следующий код:
df.loc[df['Return'] == max_dd, 'Date']
Но в сообщении об ошибке говорится:
KeyError: 'Date'
Примечание: Я могу заставить "b" работать в этом игрушечном примере, но фактические данные выдают сообщение об ошибке. Вот код действительный, используемый для импорта данных из CSV-файла:
df = pd.read_csv(FILE_NAME, parse_dates=True).reset_index()
df.set_index('Date', inplace = True) <<--- this is causing the problem
Обновлено: в "C" я ищу ПЕРВЫЙ ЭКЗЕМПЛЯР значения.
Проблема в том, что у вас, вероятно, есть пробелы в именах столбцов. Прежде чем делать все, что вы делаете, примените следующее: df.columns = df.columns.str.strip()
Затем повторите свой .loc
шаг.
@Efran - нет, в заголовках столбцов нет пробелов.
Не могли бы вы проверить, что возвращает print(df.columns)
?
Этот df.loc[df[df['Return'].eq(0)].index.max(), 'Date']
также получит ответ, который вы хотите, в вашем игрушечном примере, но не уверен, что это также относится к вашему фактическому набору данных.
print(df.columns) возвращает: Index([u'index', u'Date', u'Return'], dtype='object')
Чтобы решить все ваши проблемы, ваш код может быть написан следующим образом:
import pandas as pd
from io import StringIO
# read the data
df = pd.read_csv(StringIO("""
Date Return
1/28/2009 -0.825148
1/29/2009 -0.859997
1/30/2009 0.000000
2/2/2009 -0.909546
2/3/2009 0.000000
2/4/2009 -0.899110
2/5/2009 -0.866104
2/6/2009 0.000000
2/9/2009 -0.830099
2/10/2009 -0.885111
2/11/2009 -0.878320
2/12/2009 -0.881853
2/13/2009 -0.884432
2/17/2009 -0.947781
2/18/2009 -0.966414
2/19/2009 -1.016344
2/20/2009 -1.029667
2/23/2009 -1.087432
2/24/2009 -1.050808
2/25/2009 -1.089594
2/26/2009 -1.121556
2/27/2009 -1.105873
3/2/2009 -1.205019
3/3/2009 -1.191488
3/4/2009 -1.059311
3/5/2009 -1.135962
3/6/2009 -1.147031
3/9/2009 -1.117328
3/10/2009 -1.009050"""), sep = "\s+").reset_index()
# a) find the most negative value in the "Return" column
min_value = df["Return"].min()
print("The minimum value in the dataset is: {}".format(min_value))
# b) find the date that this minimum value occurred at
min_value_date = df.iloc[df["Return"].idxmin(), :]["Date"]
print("The minimum value in the dataset occurred on: {}".format(min_value_date))
# c) find the first instance of a specified value in the dataset closest to this
# minimum value with an index less than the minimum value index
found_value = 0
found_indices = df.index[df["Return"] == found_value].tolist()
found_correct_index = -1
for index in found_indices:
if index > df["Return"].idxmin():
break
previous_index = index
found_correct_index = previous_index
try:
print("The value searched for is {0} and it is found in the index of {1}.".format(found_value, found_correct_index))
except:
print("The value searched for of {0} was not found in the dataset.".format(found_value))
# d) find the date associated with that value
found_value_date = df.iloc[found_correct_index, :]["Date"]
print("The date associated with that found value of {0} is {1}.".format(found_value, found_value_date))
Я хочу начать с -1.205019, а затем «подняться» по столбцу «Возврат» и получить первый экземпляр определенного значения (в данном случае 0,000000). Затем я хочу вернуть дату возникновения этого значения. Общая цель состоит в том, чтобы определить диапазон «начальной даты» и «конечной даты», а затем нанести заштрихованную область, совпадающую с этим диапазоном дат.
Я отредактировал ответ. Дайте мне знать, правильно ли я адресовал (c) и (d).
Отфильтруйте свой фрейм данных для всех строк, меньших минимального значения в Return, а также Return равных нулю, чем покажите последнее значение.
df.loc[(df.index < df.Return.idxmin()) & (df['Return'] == 0), "Date"].tail(1)
Почему не 30 января или 3 февраля для d? все они равны 0.