用Pythonic方法读取数据,为热图创建分数列表?

用Pythonic方法读取数据,为热图创建分数列表?,python,pandas,dataframe,plotly-dash,Python,Pandas,Dataframe,Plotly Dash,我正试图找出一种方法,从熊猫df生成一个“z分数”,用于日历热图 。它沿“x”轴显示一周中的哪一天,沿“y”轴显示几周。每个日期都有一个数值“z分数”,创建这个z分数是我遇到麻烦的地方 My df是从csv文件创建的,该文件列出了几个不同的任务,其中包含以下列和一些示例数据: Job,Tool,Start,End A,Hammer,2020-10-03,2020-11-02 A,Drill,2020-11-05,2020-12-02 A,Hammer,2020-12-03,2020-12-30

我正试图找出一种方法,从熊猫df生成一个“z分数”,用于日历热图

。它沿“x”轴显示一周中的哪一天,沿“y”轴显示几周。每个日期都有一个数值“z分数”,创建这个z分数是我遇到麻烦的地方

My df是从csv文件创建的,该文件列出了几个不同的任务,其中包含以下列和一些示例数据:

Job,Tool,Start,End
A,Hammer,2020-10-03,2020-11-02
A,Drill,2020-11-05,2020-12-02
A,Hammer,2020-12-03,2020-12-30
该数据适用于甘特图,但需要稍加修改以用于热图。我已经能够使用熊猫来生成重要的日期:

def calendarmap():
    d1 = min(dff['Start'])

    d2 = max(dff['End'])

    delta = d2 - d1

    dates_that_matter = [d1 + dt.timedelta(i) for i in range(delta.days+1)]

    etc
不管使用什么热图方法(sns、go.heatmap等),我都需要创建一个与所用工具(z分数)对应的列表

我想写一个简单的脚本:

  • 重复我的重要约会
  • 检查该日期是否在my df中每一行的开始日期或结束日期之间
  • 如果日期出现在我的df中,它应该将z分数写入对应于每个唯一工具的列表中。有了这个示例数据,我会很高兴Hammer=0.5,Drill=1.0
  • 如果日期不存在,则分配的z分数应为0。日期仍然存在,但它应该反映出那天没有工作
  • 允许使用不同数量的工具。在此示例中,有3个z分数状态(0=无,0.5=锤击,1.0=钻孔),但z分数状态的数量可能在2到10之间波动

  • 第2步和第5步是目前我面临的挑战。在此方面的任何帮助都将不胜感激。谢谢。

    只回答数据创建问题。 工艺流程:

  • 从原始数据框的每一行创建一个从开始日期到结束日期的数据框,并将其添加到新数据框中。(创建垂直数据)
  • 添加工作负载列
  • 按日期合计工作量
  • 添加缺少的日期。(dfs.reindex())
  • 为周、周中的天和月中的月添加列。 这就完成了图形数据。 顺便说一句,为了验证,我把它转换成了一种水平格式,其中有月和日列,就像日历一样

  • 只回答数据创建问题。 工艺流程:

  • 从原始数据框的每一行创建一个从开始日期到结束日期的数据框,并将其添加到新数据框中。(创建垂直数据)
  • 添加工作负载列
  • 按日期合计工作量
  • 添加缺少的日期。(dfs.reindex())
  • 为周、周中的天和月中的月添加列。 这就完成了图形数据。 顺便说一句,为了验证,我把它转换成了一种水平格式,其中有月和日列,就像日历一样

  • 这太棒了!我在此基础上创建了用于工作负载颜色编码的dfs,然后使用DFSLABLE为热图添加日期注释。这太棒了!在此基础上,我创建了用于工作负载颜色编码的dfs,然后创建了DFSLABLE,用于在热图上标注日期。
    fig.add_trace(go.Heatmap(z = z, x = x, y = y)
    
    dfs = pd.DataFrame()
    for idx, row in df.iterrows():
        tmp_date = pd.date_range(row['Start'], row['End'], freq='1D')
        tmp_df = pd.DataFrame({'Date':pd.to_datetime(tmp_date), 'Job':row['Job'], 'Tool':row['Tool']})
        dfs = dfs.append(tmp_df, ignore_index=True)
    dfs['workload'] = dfs['Tool'].apply(lambda x: 1 if x == 'Drill' else 0.5 if x == 'Hammer' else 0.75)
    dfs.set_index('Date', inplace=True)
    dfs = dfs.groupby(dfs.index)['workload'].sum().to_frame()
    dfs = dfs.reindex(pd.date_range(dfs.index.min(), dfs.index.max(), freq='1D',name='Date'), fill_value=0, axis='index')
    dfs.reset_index(inplace=True)
    
    import calendar
    def getNweek(x):
        first_dayofweek = calendar.monthrange(x.year, x.month)[0]
        offset = (first_dayofweek - 6) % 7
        return (x.day + offset -1) // 7 + 1
    dfs['nweek'] = dfs['Date'].apply(lambda x: getNweek(x))
    dfs['month'] = dfs['Date'].dt.month
    dfs['dayofweek'] = dfs['Date'].dt.dayofweek
    
    dfs.head()
    Date    workload    nweek   month   dayofweek
    0   2020-10-03  0.5     1   10  5
    1   2020-10-04  0.5     2   10  6
    2   2020-10-05  0.5     2   10  0
    3   2020-10-06  0.5     2   10  1
    4   2020-10-07  0.5     2   10  2
    
    dfs = dfs.pivot(index='nweek', columns=['month', 'dayofweek'], values='workload')
    
    import itertools
    dow = [6,0,1,2,3,4,5]
    m = [10,11,12]
    new_cols = list(itertools.product(m,dow))
    dfs.reindex(new_cols, axis=1)
        month                    10                 11                              12
    dayofweek   6   0   1   2   3   4   5   6   0   1   ...     3   4   5   6   0   1   2   3   4   5
    nweek                                                                                   
    1   NaN     NaN     NaN     NaN     NaN     NaN     0.50    1.25    1.25    0.0     ...     1.0     1.0     1.0     NaN     NaN     2.0     2.0     0.5     0.5     0.5
    2   0.50    0.50    0.50    0.50    0.50    0.50    0.50    1.00    1.00    1.0     ...     1.0     1.0     1.0     0.5     0.5     0.5     0.5     0.5     0.5     0.5
    3   0.50    0.50    0.50    0.50    0.50    0.50    0.50    1.00    1.00    1.0     ...     1.0     1.0     1.0     0.5     0.5     0.5     0.5     0.5     0.5     0.5
    4   0.50    0.50    0.50    0.50    0.50    1.25    1.25    1.00    1.00    1.0     ...     2.0     2.0     2.0     0.5     0.5     0.5     1.0     1.0     1.0     1.0
    5   1.25    1.25    1.25    1.25    1.25    1.25    1.25    2.00    2.00    NaN     ...     NaN     NaN     NaN     1.0     1.0     1.0     1.0     NaN     NaN     NaN