根据两列中的匹配值为日期差异创建条件列

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。它是某种线性回归吗?如果您提供一些如何获得5327 的示例,也许是最好的 它只是一个随机数,你会看到相等的 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

我在这里过度使用了 il​​oc 和 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)

【讨论】:

以上是关于根据两列中的匹配值为日期差异创建条件列的主要内容,如果未能解决你的问题,请参考以下文章

ACCESS有一个表,我想根据A列或是C列两列数据中的任意数据进行查询,怎么创建查询? 哪位高人可以指点下

SQL - 从单列到两列的所有日期组合

vba代码根据两列条件插入新行

将两列与另外两列匹配

然后匹配两列中的值,然后基于R中返回的新值

比较两列中的两个数据场并获得差异