введите положительные и отрицательные значения на основе целевой даты в кадре данных - PullRequest
0 голосов
/ 11 июля 2019

У меня есть df с данными о запасах, и я хотел бы ввести отрицательные и положительные целые числа (с указанием дней) до и после target_date - согласно ниже:

Что у меня есть (дата указатель):

date      symbol    open    high    low close   volume
12/9/1988   AAPL    1.4018  1.4107  1.3839  1.3975  11239200
12/12/1988  AAPL    1.4018  1.4107  1.375   1.375   29470000
12/13/1988  AAPL    1.375   1.3839  1.3661  1.3839  30637600
12/14/1988  AAPL    1.375   1.4286  1.375   1.4196  48325200
12/15/1988  AAPL    1.4286  1.4464  1.4018  1.4107  28142800
12/16/1988  AAPL    1.4107  1.4464  1.4018  1.4332  45872400
12/19/1988  AAPL    1.4375  1.4643  1.4286  1.4554  58581600
12/20/1988  AAPL    1.4643  1.4821  1.4511  1.4643  68546800
12/21/1988  AAPL    1.4643  1.5 1.4643  1.4911  60491200
12/22/1988  AAPL    1.4911  1.5 1.4554  1.4643  26507600
12/23/1988  AAPL    1.4643  1.4779  1.4643  1.4689  10239600
12/27/1988  AAPL    1.4643  1.4821  1.4464  1.4464  14996800
12/28/1988  AAPL    1.4464  1.4554  1.4196  1.4375  12885600

Ниже приведено представление о том, что я хотел бы получить, когда target_date: 16.12.1988:

  1. создать столбец с именем "день"
  2. на целевую дату (например, 16.12.1988) - введите «0» в столбце «день»
  3. в столбце «день» - перед целевой датой введите -1 до -n (длина df до даты)
  4. в столбце «день» - после целевой даты введите от 1 до n (длина df после даты)
date       day  symbol  open    high    low close   volume
12/9/1988   -5  AAPL    1.4018  1.4107  1.3839  1.3975  11239200
12/12/1988  -4  AAPL    1.4018  1.4107  1.375   1.375   29470000
12/13/1988  -3  AAPL    1.375   1.3839  1.3661  1.3839  30637600
12/14/1988  -2  AAPL    1.375   1.4286  1.375   1.4196  48325200
12/15/1988  -1  AAPL    1.4286  1.4464  1.4018  1.4107  28142800
12/16/1988  0   AAPL    1.4107  1.4464  1.4018  1.4332  45872400
12/19/1988  1   AAPL    1.4375  1.4643  1.4286  1.4554  58581600
12/20/1988  2   AAPL    1.4643  1.4821  1.4511  1.4643  68546800
12/21/1988  3   AAPL    1.4643  1.5 1.4643  1.4911  60491200
12/22/1988  4   AAPL    1.4911  1.5 1.4554  1.4643  26507600
12/23/1988  5   AAPL    1.4643  1.4779  1.4643  1.4689  10239600
12/27/1988  6   AAPL    1.4643  1.4821  1.4464  1.4464  14996800
12/28/1988  7   AAPL    1.4464  1.4554  1.4196  1.4375  12885600

Я рассмотрел следующий подход (найден в SO, но не могу найти источник):

lenDF = (int(len(df) / 2))
df.insert(0, 'day', range(-lenDF, -lenDF + len(df)))

Это не совсем подходит для моих целей до того, как длина df до целевой даты может отличаться от целевой даты. Он не совпадает с '0' в столбце "день" с датой target_date.

Я также пытался усечь df до и после целевой даты - но та же проблема, что и в предыдущем решении - он не соответствует '0' в столбце "день" с target_date.

df_before_target = df.truncate(before=target_date)
df_after_target = df.truncate(after=target_date)

len_b4 = len(df_before_target ) - 1  # substracting 1 to account for double counting of target_date in the truncated dfs.

len_a4 = len(df_after_target )
df.insert(0, 'day', range(-len_b4, -len_a4 + len(df)))

Спасибо за любую помощь.

Ответы [ 3 ]

1 голос
/ 12 июля 2019

Я думаю, что numpy's busday_count() будет хорошо работать здесь.

Я предпочитаю работать в ISO 8601 для дат.Вы можете сделать это, используя pandas 'DatetimeIndex class:

df.index = pd.DatetimeIndex(df.index)

. Мы можем получить данные для желаемого столбца следующим образом:

days = [np.busday_count('1988-12-16', x.date()) for x in df.index]

, который повторяется для каждого pd.TimestampОбъект в вашем DatetimeIndex и вычисляет разницу (с точки зрения рабочего дня) с вашей целевой датой 1988-12-16.

Затем вы можете назначить эти данные вашему фрейму данных следующим образом:

df['day'] = days

и измените порядок столбцов, как показано в вашем сообщении:

df.reindex(columns=['day', 'symbol', 'open', 'high', 'low', 'close', 'volume'])
0 голосов
/ 11 июля 2019

Вот мой вариант подсчета дней.

dataset=pd.DataFrame(test)
dataset.head()

вывод ваших исходных данных:

      date     symbol   high
0   12/9/1988   AAPL    1.4018
1   12/12/1988  AAPL    1.4018
2   12/13/1988  AAPL    1.3750
3   12/14/1988  AAPL    1.3750
4   12/15/1988  AAPL    1.4286

from datetime import datetime
dataset=pd.DataFrame(test)
dataset['date']=pd.to_datetime(dataset['date']) 
target_date = datetime.strptime('12/16/1988', "%m/%d/%Y")
dataset['Days']= (dataset['date'] - (target_date)).dt.days
dataset.head()

Выход:

       date    symbol    high   Days
0   1988-12-09  AAPL    1.4018  -7
1   1988-12-12  AAPL    1.4018  -4
2   1988-12-13  AAPL    1.3750  -3
3   1988-12-14  AAPL    1.3750  -2
4   1988-12-15  AAPL    1.4286  -1
0 голосов
/ 11 июля 2019

У меня есть хакерское решение, но оно должно сработать.

df["day"] = df.index.values - df[df[date] == "TARGET DATE"].index[0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...