【问题标题】:How to do time continuity checks using python in pandas data-frame如何在熊猫数据框中使用python进行时间连续性检查
【发布时间】:2020-03-12 17:54:15
【问题描述】:

我有一个数据框,其中包含如下列:

colA  colB   colC    colD  colE   flag
 A     X    2018Q1    500   600    1
 A     X    2018Q2    200   800    1 
 A     X    2018Q3    100   400    1
 A     X    2018Q4    500   600    1
 A     X    2019Q1    400   7000   0
 A     X    2019Q2    1500  6100   0
 A     X    2018Q3    5600  600    1
 A     X    2018Q4    500   6007   1

 A     Y    2016Q1    900   620    1
 A     Y    2016Q2    750   850    0
 A     Y    2017Q1    750   850    1
 A     Y    2017Q2    750   850    1
 A     Y    2017Q3    750   850    1
 A     Y    2018Q1    750   850    1
 A     Y    2018Q2    750   850    1
 A     Y    2018Q3    750   850    1
 A     Y    2018Q4    750   850    1

colA, colB 级别的行通过统计检查,如果在colA, colB 级别,flag==1 的值对continuous 4 quarters 的数据进行了一次排序后。 我们必须像这样大步前进:2018Q1-2018Q4 then 2018Q2-2019Q1 .... 依此类推,如果有 4 个连续的季度并且 flag==1,那么我们将其标记为 1。

最终的输出会是这样的:

colA  colB   colC    colD  colE   flag  check_qtr
 A     X    2018Q1    500   600    1     1
 A     X    2018Q2    200   800    1     1
 A     X    2018Q3    100   400    1     1
 A     X    2018Q4    500   600    1     1
 A     X    2019Q1    400   7000   0     0   
 A     X    2019Q2    1500  6100   0     0
 A     X    2018Q3    5600  600    1     0
 A     X    2018Q4    500   6007   1     0

 A     Y    2016Q1    900   620    1     0
 A     Y    2016Q2    750   850    0     0
 A     Y    2017Q1    750   850    1     0
 A     Y    2017Q2    750   850    1     0
 A     Y    2017Q3    750   850    1     0
 A     Y    2018Q1    750   850    1     1
 A     Y    2018Q2    750   850    1     1   
 A     Y    2018Q3    750   850    1     1
 A     Y    2018Q4    750   850    1     1
  1. 我们如何使用 pandas 和 numpy 做到这一点?
  2. 我们可以使用 sql 来实现吗?

【问题讨论】:

  • 您使用的是哪个数据库?
  • 亚马逊的红移
  • 在您的样本数据第 7 行有 2018Q2 即数据未排序。是这种情况还是样本数据是这样的?
  • 如果上面不是这样,那么你可以使用下面的sql select colA , colB, colC , colD, colE, flag, CASE WHEN flag = 1 AND lead (flag, 1) OVER(PARTITION BY COLA ORDER BY colC ASC) = 1 AND lead (flag, 2) OVER(PARTITION BY COLB ORDER BY colC ASC) = 1 AND lead (flag, 3) OVER(PARTITION BY COLB ORDER BY colC ASC) = 1 THEN 1 ELSE 0 END as check_qtr from tab order by colB, colC;
  • 如何用python编写这段sql代码?

标签: sql python-3.x


【解决方案1】:

关于你的第一个问题,这可以使用 pandas 来完成: 首先,我将生成您的示例数据框:

import pandas as pd
df = pd.DataFrame({'colA':['A']*17,
                   'colB':['X']*8+['Y']*9,
                   'flag':[1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1]})
df.set_index(['colA','colB'], inplace=True) # Set index as multilevel with colA and colB

导致您的示例数据框。但是,要使用以下方法,我们需要回到正常索引:

df.reset_index(inplace=True)

  colA colB flag
0   A   X    1
1   A   X    1
2   A   X    1
3   A   X    1
4   A   X    0
5   A   X    0
6   A   X    1
7   A   X    1
8   A   Y    1
9   A   Y    0
10  A   Y    1
11  A   Y    1
12  A   Y    1
13  A   Y    1 
14  A   Y    1 
15  A   Y    1
16  A   Y    1

然后要获取您的结果列,您可以使用groupby 函数(带有一些打印以了解发生了什么):

from scipy.ndimage.interpolation import shift
import numpy as np
df['check_qtr'] = pd.Series(0,index=df.index) # Initialise your result column 
for name, group in df.groupby(['colA','colB','flag']):
    if name[2] == 1:
        print(name)
        idx = ((group.index.values - shift(group.index.values, 1, cval=-1)) == 1).astype(int) # Is the index of the following value just 1 place after current ?
        print(idx)
        bools = [idx[x:x+4].sum()==4 for x in range(len(idx))] # Are the 4 next indexes following each others ?
        print(bools)
        for idx in group.index.values[bools]: # For each index where the 4 next indexes following each others
            df.loc[idx:idx+3,'check_qtr'] = 1 #set check_qtr in row idx to row idx+3

('A', 'X', 1)
[1 1 1 1 0 1]
[True, False, False, False, False, False]
('A', 'Y', 1)
[0 0 1 1 1 1 1 1]
[False, False, True, True, True, False, False, False]

请注意,我们在进行数组索引的情况下使用 +4。因为 array[x:x+4] 将为您提供索引 x 到 x+3 处的 4 个值。 我们在使用loc 时使用+3,因为 loc 不使用相同的逻辑。它按名称而不是位置检索索引。所以在值 idx 和 idx+3 之间我们会得到 4 个值。

给你想要的结果:

       colA    colB    flag check_qtr
 0      A       X       1      1
 1      A       X       1      1
 2      A       X       1      1
 3      A       X       1      1
 4      A       X       0      0
 5      A       X       0      0
 6      A       X       1      0
 7      A       X       1      0
 8      A       Y       1      0
 9      A       Y       0      0
 10     A       Y       1      0
 11     A       Y       1      1
 12     A       Y       1      1
 13     A       Y       1      1
 14     A       Y       1      1
 15     A       Y       1      1
 16     A       Y       1      1

这可能不是完美的方法,但它可以为您提供一些关于如何使用其中一些功能的提示!

【讨论】:

  • 我们可以在python3中执行这个sql代码select colA , colB, colC , colD, colE, flag, CASE WHEN flag = 1 AND lead (flag, 1) OVER(PARTITION BY COLA ORDER BY colC ASC) = 1 AND lead (flag, 2) OVER(PARTITION BY COLB ORDER BY colC ASC) = 1 AND lead (flag, 3) OVER(PARTITION BY COLB ORDER BY colC ASC) = 1 THEN 1 ELSE 0 END as check_qtr from tab order by colB, colC;吗??
  • 我不是真正的 SQL 专家,但我认为您有两个选择。在这两种情况下,从您的 SQL 原始数据开始,您要么在使用此 SQL 提取它之前对其进行格式化,要么将其提取为原始数据从您的数据库中提取并使用 pandas 对其进行格式化。
  • Sql 让代码更短,所以我问我们是否可以在 python 中使用 pandas 数据框运行 sql 代码?
  • 结果不匹配
  • 这个问题可能会对你的目标有所帮助:stackoverflow.com/questions/45865608/… 哪些部分的结果不匹配?
猜你喜欢
  • 2019-05-31
  • 2021-07-29
  • 2020-10-02
  • 1970-01-01
  • 2022-08-09
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
相关资源
最近更新 更多