首先,我只是假设Numpy是实现这一点的最佳方式,但我对其他更合适的软件包持开放态度(Pandas ?).我希望将以下数据映射为矩阵格式(最终显示给用户).

输入数据:

1) {StartDate: datetime.date(2023, 6, 30), EndDate: datetime.date(2025, 6, 30), XCord = 3.5, YVal = 65}
2) {StartDate: datetime.date(2022, 6, 30), EndDate: datetime.date(2023, 6, 30), XCord = 0.5, YVal = 50}
3) {StartDate: datetime.date(2022, 6, 30), EndDate: datetime.date(2023, 9, 30), XCord = 5.5, YVal = 100}

符合以下要求

  1. 输入数据中的YVal将映射为所有StartDate的值<=Y<=结束日期
  2. 对位于索引值(X轴和Y轴上)之间的任何值进行线性插值
  3. 对于Y轴(日期)插值,我基于日期差进行插值.也就是说,假设你有一些约会<date_target<date_高.我根据date_low-date_high和date_target to date_low之间的天数来存储数据.例如,如果date_目标正好位于两个Y轴日期之间,则值的50%将显示在date_高行中.

Matrix X-Axis values:

0 1 2.25 3.5 4 5 6

Matrix Y-Values:

[datetime.date(2022, 9, 30)]
[datetime.date(2022, 12, 30)]
[datetime.date(2023, 6, 30)]
[datetime.date(2023, 12, 30)]
[datetime.date(2024, 6, 30)]
[datetime.date(2024, 12, 30)]
[datetime.date(2025, 6, 30)]

对于上述各输入数据示例,它们将显示:

输入1:

Date 0 1 2.25 3.5 4 5 6
datetime.date(2022, 9, 30) 0 0 0 0 0 0 0
datetime.date(2022, 12, 30) 0 0 0 0 0 0 0
datetime.date(2023, 6, 30) 0 0 0 65 0 0 0
datetime.date(2023, 12, 30) 0 0 0 65 0 0 0
datetime.date(2024, 6, 30) 0 0 0 65 0 0 0
datetime.date(2024, 12, 30) 0 0 0 65 0 0 0
datetime.date(2025, 6, 30) 0 0 0 65 0 0 0

输入2:

Date 0 1 2.25 3.5 4 5 6
datetime.date(2022, 9, 30) 25 25 0 0 0 0 0
datetime.date(2022, 12, 30) 25 25 0 0 0 0 0
datetime.date(2023, 6, 30) 25 25 0 0 0 0 0
datetime.date(2023, 12, 30) 0 0 0 0 0 0 0
datetime.date(2024, 6, 30) 0 0 0 0 0 0 0
datetime.date(2024, 12, 30) 0 0 0 0 0 0 0
datetime.date(2025, 6, 30) 0 0 0 0 0 0 0

输入3:

Date 0 1 2.25 3.5 4 5 6
datetime.date(2022, 9, 30) 0 0 0 0 0 50 50
datetime.date(2022, 12, 30) 0 0 0 0 0 50 50
datetime.date(2023, 6, 30) 0 0 0 0 0 50 50
datetime.date(2023, 12, 30) 0 0 0 0 0 25 25
datetime.date(2024, 6, 30) 0 0 0 0 0 0 0
datetime.date(2024, 12, 30) 0 0 0 0 0 0 0
datetime.date(2025, 6, 30) 0 0 0 0 0 0 0

我希望将所有这些加在一个矩阵中作为最终输出.

非常感谢!

推荐答案

你可以使用Xarray.

import datetime
import xarray as xr


input_1 = {"StartDate": datetime.date(2023, 6, 30), "EndDate": datetime.date(2025, 6, 30), "XCord": 3.5, "YVal": 65}
input_2 = {"StartDate": datetime.date(2022, 6, 30), "EndDate": datetime.date(2023, 6, 30), "XCord": 0.5, "YVal": 50}
input_3 = {"StartDate": datetime.date(2022, 6, 30), "EndDate": datetime.date(2023, 9, 30), "XCord": 5.5, "YVal": 100}
input_4 = {"StartDate": datetime.date(2023, 2, 15), "EndDate": datetime.date(2025, 2, 15), "XCord": 4.25, "YVal": 100}

Matrix_X_axis_values = [0, 1, 2.25, 3.5, 4, 5, 6]

Matrix_Y_axis_values = [
    datetime.date(2022, 9, 30),
    datetime.date(2022, 12, 30),
    datetime.date(2023, 6, 30),
    datetime.date(2023, 12, 30),
    datetime.date(2024, 6, 30),
    datetime.date(2024, 12, 30),
    datetime.date(2025, 6, 30),
]


def get_neighbour_values(arr, value):
    left_elements = [element for element in arr if element <= value]
    left_neighbour = left_elements[-1] if left_elements else None

    right_elements = [element for element in arr if element > value]
    right_neighbour = right_elements[0] if right_elements else None
    return left_neighbour, right_neighbour


for input_selected in [input_1, input_2, input_3, input_4]:
    foo = xr.DataArray(0, coords=[Matrix_Y_axis_values, Matrix_X_axis_values], dims=["X", "Y"])

    Startdate = input_selected["StartDate"]
    Enddate = input_selected["EndDate"]
    XCord = input_selected["XCord"]
    YVal = input_selected["YVal"]

    interp_startdate_from, interp_startdate_to = get_neighbour_values(Matrix_Y_axis_values, Startdate)
    interp_enddate_from, interp_enddate_to = get_neighbour_values(Matrix_Y_axis_values, Enddate)

    if XCord in Matrix_X_axis_values:
        foo.loc[interp_startdate_to:interp_enddate_to, XCord] = YVal
    else:
        left_XCord, right_XCord = get_neighbour_values(Matrix_X_axis_values, XCord)

        # linear interpolation
        XCord_range = right_XCord - left_XCord
        left_YVal = YVal * (right_XCord - XCord) / XCord_range
        right_YVal = YVal * (XCord - left_XCord) / XCord_range

        foo.loc[interp_startdate_to:interp_enddate_to, left_XCord] = left_YVal
        foo.loc[interp_startdate_to:interp_enddate_to, right_XCord] = right_YVal

    if interp_startdate_to == interp_enddate_to:
        # startdate and Enddate in same bin
        weight = (Enddate - Startdate).days / (interp_startdate_to - interp_startdate_from).days
        foo.loc[interp_startdate_to, :] = foo.loc[interp_startdate_to, :] * weight
    else:
        # Startdate and Enddate in seperate bins
        if interp_startdate_to and interp_startdate_from:
            # date-interpolation for start
            weight = (interp_startdate_to - Startdate).days / (interp_startdate_to - interp_startdate_from).days
            foo.loc[interp_startdate_to, :] = foo.loc[interp_startdate_to, :] * weight

        if interp_enddate_to and interp_enddate_from:
            # date-interpolation for end
            weight = (Enddate - interp_enddate_from).days / (interp_enddate_to - interp_enddate_from).days
            foo.loc[interp_enddate_to, :] = foo.loc[interp_enddate_to, :] * weight

    print(foo)

与您的示例相比,第一个示例产生了不同的结果.但我认为,这是正确的计算方法.我确实认为表中的日期是垃圾箱的上限.

我确实添加了第四个示例来展示X和Y的同时插值.

Python相关问答推荐

仅使用2种 colored颜色 创建热图

使用Curses for Python保存和恢复终端窗口内容

在Python中使用一行try

如何在Python中按组应用简单的线性回归?

使用Beautiful Soup获取第二个srcset属性

用Python获取HTML Span类中的数据

使用Python Cerberus初始化一个循环数据 struct (例如树)(v1.3.5)

opencv Python稳定的图标识别

Pandas 除以一列中出现的每个值

从numpy数组和参数创建收件箱

Pandas - groupby字符串字段并按时间范围 Select

django禁止直接分配到多对多集合的前端.使用user.set()

无法定位元素错误404

Asyncio:如何从子进程中读取stdout?

如何使用scipy的curve_fit与约束,其中拟合的曲线总是在观测值之下?

如何在turtle中不使用write()来绘制填充字母(例如OEG)

下三角形掩码与seaborn clustermap bug

在代码执行后关闭ChromeDriver窗口

人口全部乱序 - Python—Matplotlib—映射

在matplotlib中使用不同大小的标记顶部添加批注