Python pandas - пересматривать каждый второй ряд, а не каждый второй рабочий день - PullRequest
0 голосов
/ 27 июня 2018

Я работаю с данными о ценах на акции и хотел бы, чтобы resample() возвращал каждый второй ряд, а не каждый второй рабочий день (resample('2B')). Препятствием является любой праздник, который приземляется в будний день. Смотрите ниже, День MLK - понедельник, 15 января 2018 года:

import pandas as pd

data = '''\
date,price
2018-01-08,88.28
2018-01-09,88.22
2018-01-10,87.82
2018-01-11,88.08
2018-01-12,89.6
2018-01-16,88.35
2018-01-17,90.14
2018-01-18,90.1
2018-01-19,90.0
2018-01-22,91.61
2018-01-23,91.9
2018-01-24,91.82
2018-01-25,92.33
2018-01-26,94.06'''

fileobj = pd.compat.StringIO(data)
df = pd.read_csv(fileobj, parse_dates=['date'], index_col=[0])

df_resample = df.resample('2B').min()
print(df_resample)

Выход:

            price
2018-01-08  88.22
2018-01-10  87.82
2018-01-12  89.60
2018-01-16  88.35
2018-01-18  90.00
2018-01-22  91.61
2018-01-24  91.82
2018-01-26  94.06

Я бы хотел, чтобы сэмплер подскочил с 1/12 до 1/17. Я знаю, что могу использовать df['price'].loc[::2] для доставки df.resample('2B').last(), но мне нужно также использовать min(), max() и sum().

Спасибо.

Ожидаемый результат:

enter image description here

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Используя np.repeat с нарезкой массива, вы можете создать пересчитанный кадр данных, в котором дата (индекс) будет повторяться дважды.

df_resample = df.set_index(np.repeat(df.index[::2],2)[:len(df)])
# outputs:
            price
date
2018-01-08  88.28
2018-01-08  88.22
2018-01-10  87.82
2018-01-10  88.08
2018-01-12  89.60
2018-01-12  88.35
2018-01-17  90.14
2018-01-17  90.10
2018-01-19  90.00
2018-01-19  91.61
2018-01-23  91.90
2018-01-23  91.82
2018-01-25  92.33
2018-01-25  94.06

Тогда обычная группировка дает желаемый результат:

df_resampled.groupby(level=0).agg(['last', 'min', 'max', 'sum'])

            price
             last    min    max     sum
date
2018-01-08  88.22  88.22  88.28  176.50
2018-01-10  88.08  87.82  88.08  175.90
2018-01-12  88.35  88.35  89.60  177.95
2018-01-17  90.10  90.10  90.14  180.24
2018-01-19  91.61  90.00  91.61  181.61
2018-01-23  91.82  91.82  91.90  183.72
2018-01-25  94.06  92.33  94.06  186.39
0 голосов
/ 27 июня 2018

Я думаю, это тоже может сработать, как бы поменять местами шаги ...

df['price'].rolling(window=2).max().iloc[1::2]
0 голосов
/ 27 июня 2018

Для стабильного решения я бы как-то пересмотрел B-дни.

Но если вы сбрасываете индекс, вы можете использовать номера индексов и группировать:

df = df.reset_index()
df_resample = df.groupby(df.index // 2).min()
print(df_resample)

Возвращает:

        date  price
0 2018-01-08  88.22
1 2018-01-10  87.82
2 2018-01-12  88.35
3 2018-01-17  90.10
4 2018-01-19  90.00
5 2018-01-23  91.82
6 2018-01-25  92.33

Или Вы можете сделать что-то вроде этого:

g = np.arange(len(df))// 2
df_resample = df.groupby(g).agg(['last','min','max','sum'])
df_resample.insert(0, 'Date', df.index[1::2])

print(df_resample)

Возвращает:

        Date  price                      
               last    min    max     sum
0 2018-01-09  88.22  88.22  88.28  176.50
1 2018-01-11  88.08  87.82  88.08  175.90
2 2018-01-16  88.35  88.35  89.60  177.95
3 2018-01-18  90.10  90.10  90.14  180.24
4 2018-01-22  91.61  90.00  91.61  181.61
5 2018-01-24  91.82  91.82  91.90  183.72
6 2018-01-26  94.06  92.33  94.06  186.39
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...