当前位置: 首页 > 知识库问答 >
问题:

计算每组每 n 天相对于带条件行的斜率

潘坚白
2023-03-14

我有以下数据帧(示例):

import pandas as pd

data = [['A', '2022-09-01', False, 2], ['A', '2022-09-02', False, 1], ['A', '2022-09-03', False, 1], ['A', '2022-09-04', True, 3], 
        ['A', '2022-09-05', False, 3], ['A', '2022-09-06', False, 2], ['A', '2022-09-07', False, 1], ['A', '2022-09-07', False, 2], 
        ['A', '2022-09-08', False, 4], ['A', '2022-09-09', False, 2],
        ['B', '2022-09-01', False, 2], ['B', '2022-09-02', False, 2], ['B', '2022-09-03', False, 4], ['B', '2022-09-04', False, 2], 
        ['B', '2022-09-05', True, 2], ['B', '2022-09-06', False, 2], ['B', '2022-09-07', False, 1], ['B', '2022-09-08', False, 3], 
        ['B', '2022-09-09', False, 3], ['B', '2022-09-10', False, 2]]
df = pd.DataFrame(data = data, columns = ['group', 'date', 'indicator', 'value'])

# Add diff_days which is difference in days with closest row with True condition per group
df['date'] = pd.to_datetime(df['date'])

df = (
    pd.merge_asof(df.sort_values('date'), 
                  df.loc[df['indicator'], ['group','date']].sort_values('date')
                    .assign(diff_days=lambda x: x['date']), 
                  by='group', on='date', direction='nearest')
      .assign(diff_days=lambda x: (x['date']-x['diff_days']).dt.days)
      .sort_values(['group','date'])
      .reset_index(drop=True)
)

   group       date  indicator  value  diff_days
0      A 2022-09-01      False      2         -3
1      A 2022-09-02      False      1         -2
2      A 2022-09-03      False      1         -1
3      A 2022-09-04       True      3          0
4      A 2022-09-05      False      3          1
5      A 2022-09-06      False      2          2
6      A 2022-09-07      False      2          3
7      A 2022-09-07      False      1          3
8      A 2022-09-08      False      4          4
9      A 2022-09-09      False      2          5
10     B 2022-09-01      False      2         -4
11     B 2022-09-02      False      2         -3
12     B 2022-09-03      False      4         -2
13     B 2022-09-04      False      2         -1
14     B 2022-09-05       True      2          0
15     B 2022-09-06      False      2          1
16     B 2022-09-07      False      1          2
17     B 2022-09-08      False      3          3
18     B 2022-09-09      False      3          4
19     B 2022-09-10      False      2          5

我想添加一个名为“slope”的列,该列相对于每组条件为“指标 = True”的行返回 n 天的斜率(本例 n = 3)。以下是所需的输出:

data = [['A', '2022-09-01', False, 2, -3, -0.5], ['A', '2022-09-02', False, 1, -2, -0.5], ['A', '2022-09-03', False, 1, -1, -0.5], ['A', '2022-09-04', True, 3, 0, 0], 
        ['A', '2022-09-05', False, 3, 1, -0.5], ['A', '2022-09-06', False, 2, 2, -0.5], ['A', '2022-09-07', False, 2, 3, -0.5], ['A', '2022-09-07', False, 1, 3, 0.5], 
        ['A', '2022-09-08', False, 4, 4, 0.5], ['A', '2022-09-09', False, 2, 5, 0.5],
        ['B', '2022-09-01', False, 2, -4], ['B', '2022-09-02', False, 2, -3, 0], ['B', '2022-09-03', False, 4, -2, 0], ['B', '2022-09-04', False, 2, -1, 0], 
        ['B', '2022-09-05', True, 2, 0, 0], ['B', '2022-09-06', False, 2, 1, 0.5], ['B', '2022-09-07', False, 1, 2, 0.5], ['B', '2022-09-08', False, 3, 3, 0.5], 
        ['B', '2022-09-09', False, 3, 4, -1], ['B', '2022-09-10', False, 2, 5, -1]]
df_desired = pd.DataFrame(data = data, columns = ['group', 'date', 'indicator', 'value', 'diff_days', 'slope'])

   group        date  indicator  value  diff_days  slope
0      A  2022-09-01      False      2         -3   -0.5
1      A  2022-09-02      False      1         -2   -0.5
2      A  2022-09-03      False      1         -1   -0.5
3      A  2022-09-04       True      3          0    0.0
4      A  2022-09-05      False      3          1   -0.5
5      A  2022-09-06      False      2          2   -0.5
6      A  2022-09-07      False      2          3   -0.5
7      A  2022-09-07      False      1          3    0.5
8      A  2022-09-08      False      4          4    0.5
9      A  2022-09-09      False      2          5    0.5
10     B  2022-09-01      False      2         -4    NaN
11     B  2022-09-02      False      2         -3    0.0
12     B  2022-09-03      False      4         -2    0.0
13     B  2022-09-04      False      2         -1    0.0
14     B  2022-09-05       True      2          0    0.0
15     B  2022-09-06      False      2          1    0.5
16     B  2022-09-07      False      1          2    0.5
17     B  2022-09-08      False      3          3    0.5
18     B  2022-09-09      False      3          4   -1.0
19     B  2022-09-10      False      2          5   -1.0

让我们解释一下 B 组的计算。斜率(使用 “diff_days” 作为 x 值)相对于指标 == True 的行计算 n = 3,即数据框中的第 15 行:

    < li >对于第12、13、14行,斜率为:Lin regressive([-3,-2,-1],[2,4,2])=0 < li >第11行是单独的,因为它不符合特定行的3天范围(indicator==True),这意味着:Lin regressive([-4],[2])=NaN < li >对于第16、17、18行,斜率为:Lin regressive([1,2,3],[2,1,3])=0.5 < li >对于第19、20行,斜率为:linregressive([4,5],[3,2])=-1.0

请注意:带有条件(指示符==true)的行的斜率值应为0。

所以,我想知道是否有人知道如何使用熊猫计算n天相对于每组某一行的斜率?

共有1个答案

段干飞翔
2023-03-14

你举的例子让我有点困惑——10(你所说的11排)有错误吗?)如果我理解正确的话,您想要的是在a) indicator变为真或b)每3行之后将每个组计为新组。可以这样做:

from scipy.stats import linregress

def count_every_n(grp, n):
    return pd.Series([k // n for k in range(len(grp))])

def get_slope(grp):
    return pd.Series(linregress(grp.diff_days, grp.value).slope, index=grp.index)

indicator_change = (df.indicator != df.indicator.shift()).cumsum()

every_n_within_groups = (df
                         .groupby(indicator_change, group_keys=False)
                         .apply(lambda g: count_every_n(g, n=3))
                         .reset_index(drop=True))

df['slope'] = (df
               .groupby([indicator_change, every_n_within_groups])
               .apply(get_slope)
               .reset_index(drop=True)
               .fillna(0))
 类似资料:
  • 我有以下数据帧(示例): 我想创建一个名为“斜率”的列,它显示每组每n(n=3)天的斜率。这意味着当第一个日期是“2022-09-01”和3天后用于计算时。斜率可以使用“diff_days”(通过与每组第一个值的差异计算)和“值”列来计算。以下是所需的输出: 以下是一些示例计算,可为您提供一个想法: A组前3天:斜率([0,1,3],[2,1,3])=0.43 A组3天后:斜率([5,6,6],[

  • 我有以下数据帧(示例): 我想计算每组n行相对于条件行的斜率(指示符==true)。这意味着它应该返回一个列“斜率”,其中斜率在条件行之前和之后,该行的斜率应该为0。除此之外,我想返回一个名为“id”的列,它实际上是表示条件行之前(负)或之后(正)斜率的值的组id。这是所需的输出: 以下是A组的一些解释: 第0,1和2行是斜率为(x=[-3,-2,-1], y=[2,1,1])=-0.5的条件行(

  • 问题内容: 我有一个有趣的查询需要做。我有一张表,其中有一列包含ip地址编号(使用)和一列。我希望能够计算每天有唯一IP地址列的数量。也就是说,每天有多少个不同的ip行。因此,例如,如果一个IP地址在同一天两次,则在最终计数中将计为1;但是,如果同一IP地址在另一天,则将被计算为第二个计数。 示例数据: 问题答案: SQLFiddle演示

  • 准备数据: CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL); INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2), (2000,2

  • 问题内容: 可以说我有一个名为’ ‘的mysql表,具有以下值: 我想生成一份报告,说明每天有多少只动物报名(我不在乎一天中的时间)。因此,我从上面的示例表中寻找的最终结果是: 有没有一种方法可以在mysql中执行此操作,或者我需要使用另一种语言(如PHP)来计算总数吗? 任何想法表示赞赏,谢谢 问题答案: 会给您您所追求的。

  • 问题内容: 我有一个sql代码,可以获取每个员工的总工作时间及其超时时间。我想计算他当天的总加班时间。你能帮我吗?8小时是每天的常规时间。 这是代码 样品输出 我想要的是这样的 问题答案: 你可以做这样的事情 这是 SQLFiddle 演示 您需要为提供真正的默认值,并针对当他们。在一个极端的情况下,如果s是由员工有一天到另一天回家而造成的,那么这些默认值可能分别是和,因为您要计算每个日历日的加班