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

计算每组每n天的斜率

韩鸿
2023-03-14

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

import pandas as pd

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

df['date'] = pd.to_datetime(df['date'])
df['diff_days'] = (df['date']-df['date'].groupby(df['group']).transform('first')).dt.days

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

我想创建一个名为“斜率”的列,它显示每组每n(n=3)天的斜率。这意味着当第一个日期是“2022-09-01”和3天后用于计算时。斜率可以使用“diff_days”(通过与每组第一个值的差异计算)和“值”列来计算。以下是所需的输出:

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

   group        date  value  diff_days  slope
0      A  2022-09-01      2          0   0.43
1      A  2022-09-02      1          1   0.43
2      A  2022-09-04      3          3   0.43
3      A  2022-09-06      2          5  -0.50
4      A  2022-09-07      1          6  -0.50
5      A  2022-09-07      2          6  -0.50
6      A  2022-09-08      4          7  -2.00
7      A  2022-09-09      2          8  -2.00
8      B  2022-09-01      2          0   0.14
9      B  2022-09-03      4          2   0.14
10     B  2022-09-04      2          3   0.14
11     B  2022-09-05      2          4  -0.50
12     B  2022-09-07      1          6  -0.50
13     B  2022-09-08      3          7  -0.50
14     B  2022-09-10      2          9  -0.50

以下是一些示例计算,可为您提供一个想法:

  • A组前3天:斜率([0,1,3],[2,1,3])=0.43
  • A组3天后:斜率([5,6,6],[2,1,2])=-0.5
  • A组3天后的斜率([7,8],[4,2])=-2.0

所以我想知道是否有人知道如何确定每组每 n 天(这种情况 3 天)的斜率?请注意:并非所有日期都包括在内,因此实际上每n天一次。

共有3个答案

谯皓君
2023-03-14

一个可能的解决方案,使用熊猫Groupby转换应用

# size of the blocks
n = 3

# this is to form blocks of 3 elements for each group
df['blk'] = df.groupby('group')['date'].transform(
    lambda x: np.repeat(range(int(np.ceil(len(x)/n))), n)[range(len(x))])

# this function calculates the slopes for each block of 3 
def f(x):
    return x.assign(slope = np.polyfit(x['diff_days'], x['value'], 1)[0])

df.groupby(['group', 'blk'], group_keys=False).apply(f).drop('blk', axis=1)

输出:

   group       date  value  diff_days     slope
0      A 2022-09-01      2          0  0.428571
1      A 2022-09-02      1          1  0.428571
2      A 2022-09-04      3          3  0.428571
3      A 2022-09-06      2          5 -0.500000
4      A 2022-09-07      1          6 -0.500000
5      A 2022-09-07      2          6 -0.500000
6      A 2022-09-08      4          7 -2.000000
7      A 2022-09-09      2          8 -2.000000
8      B 2022-09-01      2          0  0.142857
9      B 2022-09-03      4          2  0.142857
10     B 2022-09-04      2          3  0.142857
11     B 2022-09-05      2          4  0.214286
12     B 2022-09-07      1          6  0.214286
13     B 2022-09-08      3          7  0.214286
14     B 2022-09-10      2          9  0.111111
袁宜民
2023-03-14

因此,您需要:

  1. 将每个组分成n个元素组(或末尾更少)-使用Numpyarray_split
  2. 计算斜率-使用Numpy Poly说不定
  3. 追加n次(或末尾更少)

这里是:

n = 3
slopes = []
for k, g in df.groupby('group'):
    a = np.array_split(g['diff_days'].values, n)
    b = np.array_split(g['value'].values, n)
    for ab in zip(a,b):
        for x in ab[0]:
            slopes.append(np.polyfit(ab[0], ab[1], 1)[0].round(2))

df['slopes'] = slopes
金承嗣
2023-03-14
df['n'] = df.groupby('group').cumcount() // 3
df.merge(
    df
    .groupby(['group', 'n'])
    .apply(lambda s: np.polyfit(s['diff_days'], s['value'], 1)[0])
    .reset_index(name='slope')
)
    < li >使用< code>cumcount为每个组创建一个顺序计数器,然后除以< code>3得到< code>3行的块 < li >按< code>group列对数据帧以及块进行分组,并用< code>np.polyfit进行聚合,以获得斜率 < li> 合并聚合帧回到原始数据帧,以广播< code >斜率值
   group       date  value  diff_days  n     slope
0      A 2022-09-01      2          0  0  0.428571
1      A 2022-09-02      1          1  0  0.428571
2      A 2022-09-04      3          3  0  0.428571
3      A 2022-09-06      2          5  1 -0.500000
4      A 2022-09-07      1          6  1 -0.500000
5      A 2022-09-07      2          6  1 -0.500000
6      A 2022-09-08      4          7  2 -2.000000
7      A 2022-09-09      2          8  2 -2.000000
8      B 2022-09-01      2          0  0  0.142857
9      B 2022-09-03      4          2  0  0.142857
10     B 2022-09-04      2          3  0  0.142857
11     B 2022-09-05      2          4  1  0.214286
12     B 2022-09-07      1          6  1  0.214286
13     B 2022-09-08      3          7  1  0.214286
14     B 2022-09-10      2          9  2  0.111111
 类似资料:
  • 我有以下数据帧(示例): 我想添加一个名为“slope”的列,该列相对于每组条件为“指标 = True”的行返回 n 天的斜率(本例 n = 3)。以下是所需的输出: 让我们解释一下 B 组的计算。斜率(使用 “diff_days” 作为 x 值)相对于指标 == True 的行计算 n = 3,即数据框中的第 15 行: < li >对于第12、13、14行,斜率为:Lin regressive

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

  • 准备数据: 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)来计算总数吗? 任何想法表示赞赏,谢谢 问题答案: 会给您您所追求的。

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

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