2

Say I have a pd.Series of daily S&P 500 values, and I would like to filter this series to get the first business day and the associated value of each week.

So, for instance, my filtered series would contain the 5 September 2017 (Tuesday - no value for the Monday), then 11 September 2017 (Monday).

Source series: 
2017-09-01    2476.55
2017-09-05    2457.85
2017-09-06    2465.54
2017-09-07    2465.10
2017-09-08    2461.43
2017-09-11    2488.11
2017-09-12    2496.48

Filtered series
2017-09-01    2476.55
2017-09-05    2457.85
2017-09-11    2488.11

My solution currently consists of:

mask     = SP500.apply(lambda row: SP500[row.name - datetime.timedelta(days=row.name.weekday()):].index[0], axis=1).unique()
filtered = SP500.loc[mask]

This however feels suboptimal/non-pythonic. Any better/faster/cleaner solutions?

3 Answers3

1
df.sort_index().assign(week=df.index.get_level_values(0).week).drop_duplicates('week',keep='first').drop('week',1)
Out[774]: 
              price
2017-09-01  2476.55
2017-09-05  2457.85
2017-09-11  2488.11
BENY
  • 317,841
  • 20
  • 164
  • 234
1

Using resample on pd.Series.index.to_series

s[s.index.to_series().resample('W').first()]

2017-09-01    2476.55
2017-09-05    2457.85
2017-09-11    2488.11
dtype: float64
piRSquared
  • 285,575
  • 57
  • 475
  • 624
0

I'm not sure that the solution you give works, since the .apply method for series can't access the index, and doesn't have an axis argument. What you gave would work on a DataFrame, but this is simpler if you have a dataframe:

#Make some fake data
x = pd.DataFrame(pd.date_range(date(2017, 10, 9), date(2017, 10, 23)), columns = ['date'])
x['value'] = x.index
print(x)
         date  value
0  2017-10-09      0
1  2017-10-10      1
2  2017-10-11      2
3  2017-10-12      3
4  2017-10-13      4
5  2017-10-14      5
6  2017-10-15      6
7  2017-10-16      7
8  2017-10-17      8
9  2017-10-18      9
10 2017-10-19     10
11 2017-10-20     11
12 2017-10-21     12
13 2017-10-22     13
14 2017-10-23     14

#filter
filtered = x.groupby(x['date'].apply(lambda d: d-timedelta(d.weekday())), as_index = False).first()
print(filtered)
        date  value
0 2017-10-09      0
1 2017-10-16      7
2 2017-10-23     14
Jacob H
  • 345
  • 1
  • 11