python - 根据数据框中的目标日期输入正值和负值
问题描述
我有一个带有股票数据的 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
下面是我想要的目标日期为 12/16/1988 的表示:
- 创建一个名为“day”的列
- 在目标日期(例如,1988 年 12 月 16 日) - 在“天”列中输入“0”
- 在“天”列中 - 在目标日期之前输入 -1 到 -n(日期之前的 df 长度)
- 在“天”列中 - 在目标日期之后输入 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 长度可能与目标日期之后的不同之前,这并不完全适合我的目的。它与 target_date 的“day”列中的“0”不匹配。
我还尝试在目标日期之前和之后截断 df - 但与上述解决方案相同的问题 - 它与 target_date 的“day”列中的“0”不匹配。
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)))
感谢您的任何帮助。
解决方案
我认为numpybusday_count()
在这里会很好用。
我更喜欢在日期中使用ISO 8601表示法。你可以通过使用 pandas 的DatetimeIndex
类来做到这一点:
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'])
推荐阅读
- excel - 如何以用户形式将数据传输到同一工作簿中的不同工作表(使用 ComboBox1)?
- excel - 删除行(向后工作),但使用范围变量?
- node.js - Mongo 和 Node.js 查找和聚合
- python - 将日历日期转换为朱利安日期 - python
- c - while (fgets (buffer, 1024, fp) != NULL) in while (fgets (buffer, 1024, fp) != NULL)
- node.js - MongoDB中的日期操作和比较
- wordpress - React/Gatsby/Wordpress 卡在“源和转换节点”上
- ios - 使用 CTCellularPlanProvisioningRequest 获取 iccid
- youtube-api - 实时字幕中的 V 形标记被清理为 >
- node.js - 更新后返回数组属性的大小