根据两列中的匹配值为日期差异创建条件列
Posted
技术标签:
【中文标题】根据两列中的匹配值为日期差异创建条件列【英文标题】:Create conditional column for Date Difference based on matching values in two columns 【发布时间】:2019-09-21 16:49:21 【问题描述】:我有一个数据框,我正在努力根据其他列创建一个列,我将分享示例数据的问题。
Date Target1 Close
0 2019-04-17 209.2440 203.130005
1 2019-04-17 212.2155 203.130005
2 2019-04-17 213.6330 203.130005
3 2019-04-17 213.0555 203.130005
4 2019-04-17 212.6250 203.130005
5 2019-04-17 212.9820 203.130005
6 2019-04-17 213.1395 203.130005
7 2019-04-16 209.2860 199.250000
8 2019-04-16 209.9055 199.250000
9 2019-04-16 210.3045 199.250000
我想创建另一列(对于每个观察)(例如称为days_to_hit_target
),它是天数的差异,以便接近命中(或非常接近特定日期的目标),当它关闭时非常密切相关,然后计算天差并将它们放在 days_to_hit_target 列中。
【问题讨论】:
请同时发布所需的输出。 这意味着,如果今天收盘价是 203.13,那么目标也变得有点相等的那一天让我们说 203.15 并越过它,我们计算第一个日期和当它热的日期之间的天数差目标。 我仍然不确定您如何计算days_to_hit_target
。它是某种线性回归吗?如果您提供一些如何获得53
和27
的示例,也许是最好的
它只是一个随机数,你会看到相等的 close 值,它们会重复。因此,只是收盘价达到/超过相同目标值时的日期差异。
好的,我会尽快发布的
【参考方案1】:
注意我使用 python 3.7.1 和 pandas 0.23.4。我想出了一些非常肮脏的东西;我确信有一种更简洁、更有效的方法。
### Create sample data
date_range = pd.date_range(start="1/1/2018", end="20/1/2018", freq="6H", closed="right")
target1 = np.random.uniform(10, 30, len(date_range))
close = [[i]*4 for i in np.random.uniform(10,30, len(date_range)//4)]
close_flat = np.array([item for sublist in close for item in sublist])
df = pd.DataFrame(np.array([np.array(date_range.date), target1,
close_flat]).transpose(), columns=["date", "target", "close"])
### Create the column you need
# iterating over the days and finding days when the difference between
# "close" of current day and all "target" is lower than 0.25 OR the "target"
# value is greater than "close" value.
thresh = 0.25
date_diff_arr = np.zeros(len(df))
for i in range(0,len(df),4):
diff_lt_thresh = df[(abs(df.target-df.close.iloc[i]) < thresh) | (df.target > df.close.iloc[i])]
# only keep the findings from the next day onwards
diff_lt_thresh = diff_lt_thresh.loc[i+4:]
if not diff_lt_thresh.empty:
# find day difference only if something under thresh is found
days_diff = (diff_lt_thresh.iloc[0].date - df.iloc[i].date).days
else:
# otherwise write it as nan
days_diff = np.nan
# fill in the np.array which will be used to write to the df
date_diff_arr[i:i+4] = days_diff
df["date_diff"] = date_diff_arr
样本输出:
0 2018-01-01 21.64 26.7319 2.0
1 2018-01-01 22.9047 26.7319 2.0
2 2018-01-01 26.0945 26.7319 2.0
3 2018-01-02 10.2155 26.7319 2.0
4 2018-01-02 17.5602 11.0507 1.0
5 2018-01-02 12.0368 11.0507 1.0
6 2018-01-02 19.5923 11.0507 1.0
7 2018-01-03 21.8168 11.0507 1.0
8 2018-01-03 11.5433 16.8862 1.0
9 2018-01-03 27.3739 16.8862 1.0
10 2018-01-03 26.9073 16.8862 1.0
11 2018-01-04 19.6677 16.8862 1.0
12 2018-01-04 25.3599 27.3373 1.0
13 2018-01-04 22.7479 27.3373 1.0
14 2018-01-04 18.7246 27.3373 1.0
15 2018-01-05 25.4122 27.3373 1.0
16 2018-01-05 28.3294 23.8469 1.0
【讨论】:
你为什么用它 - range(0,len(df),4) 因为我的样本数据中每天有 4 个数据点;您的样本中每天有 7 个数据点。 您的输出也不完全是日期的差异,它们似乎是 4、8、15 或 nan,这似乎是错误的! 感谢您的澄清。我将进行修改。这样做是因为脚本不会在超过该值时查找。 我认为你想要你的价值接近目标的日期。脚本(和随附的 cmets)阐明了这一点。 感谢您仍在尝试。这是最重要的:)。我稍微修改了我的脚本。它应该现在做你正在寻找的东西。【参考方案2】:这应该可行:
daysAboveTarget = []
for i in range(len(df.Date)):
try:
dayAboveTarget = df.iloc[i:].loc[(df.Close > df.Target1[i])]['Date'].iloc[0]
except IndexError:
dayAboveTarget = None
daysAboveTarget.append(dayAboveTarget)
daysAboveTarget = pd.Series(daysAboveTarget)
df['days_to_hit_target'] = daysAboveTarget - df.Date
我在这里过度使用了 iloc 和 loc,所以让我解释一下。 变量 dayAboveTarget 获取价格收于目标上方的日期。第一个 iloc 将数据帧子集到仅未来日期,第一个 loc 找到实际结果,第二个 iloc 仅获得第一个结果。对于价格从未超过目标的日子,我们需要例外。
【讨论】:
您的问题被标记为 Python2,因此您可能需要更改范围函数 它显示了我消极的日子,我想,还不清楚,我又问了一遍,请你检查下面的链接。 ***.com/questions/55966950/… 如果按“日期”对 df 进行排序,则不应得到负值【参考方案3】:也许更快一点的解决方案:
import pandas as pd
# df is your DataFrame
df["Date"] = pd.to_datetime(df["Date"])
df = df.sort_values("Date")
def days_to_hit(x, no_hit_default=None):
return next(
((df["Date"].iloc[j+x.name] - x["Date"]).days
for j in range(len(df)-x.name)
if df["Close"].iloc[j+x.name] >= x["Target1"]), no_hit_default)
df["days_to_hit_target"] = df.apply(days_to_hit, axis=1)
【讨论】:
以上是关于根据两列中的匹配值为日期差异创建条件列的主要内容,如果未能解决你的问题,请参考以下文章