Python 如何基于时间差计算特定值的出现次数

Python 如何基于时间差计算特定值的出现次数,python,pandas,Python,Pandas,我希望根据特定的时间增量计算列中出现的次数。考虑下面的数据集示例: Date Type 0 2016-04-01 A 1 2016-04-01 A 2 2016-04-02 A 3 2016-04-02 B 4 2016-04-03 C 5 2016-04-04 B 6 2016-04-05 C 7 2016-04-06 C 8 2016-04-06 A 我想创建一个列,其中包含同一类型的注册频率,例如最近两天,例如:

我希望根据特定的时间增量计算列中出现的次数。考虑下面的数据集示例:

         Date  Type
0  2016-04-01  A
1  2016-04-01  A
2  2016-04-02  A
3  2016-04-02  B
4  2016-04-03  C
5  2016-04-04  B
6  2016-04-05  C    
7  2016-04-06  C
8  2016-04-06  A
我想创建一个列,其中包含同一类型的注册频率,例如最近两天,例如:

         Date  Type N_Occs_Last_2_Days
0  2016-04-01  A    1
1  2016-04-01  A    2
2  2016-04-02  A    3
3  2016-04-02  B    1
4  2016-04-03  C    1
5  2016-04-04  B    1
6  2016-04-05  C    1    
7  2016-04-06  C    2
8  2016-04-06  A    1

我发现了一些关于类似问题的信息:,但我很难提取计数。有人能给我指出正确的方向吗?

我会在一个单独的数据结构中计算出现的次数

对日期
x
进行循环,并将其与以前的
n
日期分组,然后计算该类型的出现次数


现在,由于很难处理日期类型,所以在将它们分组之前,先对它们进行散列(或分配一个唯一的数字)。

我将在单独的数据结构中计算出现的次数

对日期
x
进行循环,并将其与以前的
n
日期分组,然后计算该类型的出现次数


现在,由于很难处理日期类型,所以在将它们分组之前,先对它们进行散列(或分配唯一的数字)。

使用
groupby.cumcount

输出

print(df)
        Date Type  N_Occs_Last_2_Days
0 2016-04-01    A                   1
1 2016-04-01    A                   2
2 2016-04-02    A                   3
3 2016-04-02    B                   1
4 2016-04-03    C                   1
5 2016-04-04    B                   1
6 2016-04-05    C                   1
7 2016-04-06    C                   2
8 2016-04-06    A                   1

groupby.cumcount
用于:

输出

print(df)
        Date Type  N_Occs_Last_2_Days
0 2016-04-01    A                   1
1 2016-04-01    A                   2
2 2016-04-02    A                   3
3 2016-04-02    B                   1
4 2016-04-03    C                   1
5 2016-04-04    B                   1
6 2016-04-05    C                   1
7 2016-04-06    C                   2
8 2016-04-06    A                   1

我已经设法用了很多变通办法。如果有人有任何改进此代码的建议,他们将非常受欢迎,因为它最终将被专业地使用

test['Date'] = pd.to_datetime(test['Date'])

df = pd.get_dummies(test, columns=['Type']).set_index('Date')
df = df.apply(lambda x: x.rolling('2D').sum())
df['Type'] = test['Type'].values

# Prevent a double index error (dates are not unique)
df.reset_index(inplace=True)


type_cols = {'A': 'Type_A',
             'B': 'Type_B',
             'C': 'Type_C'}

for typ, col in type_cols.items():
    df.loc[df['Type'] == typ, 'N_occs'] = df[col]

test['N_occs'] = df['N_occs'].values
首先,我们提取虚拟编码,将索引设置为日期后,我们可以应用panda的滚动函数对这些计数求和。然后,我们根据类型选择适当的列,并将其复制到
N\u occs
。然后将其复制回原始数据帧。两个框架如下所示:

print(df)
        Date  Type_A  Type_B  Type_C Type  N_occs
0 2016-04-01     1.0     0.0     0.0    A     1.0
1 2016-04-01     2.0     0.0     0.0    A     2.0
2 2016-04-02     3.0     0.0     0.0    A     3.0
3 2016-04-02     3.0     1.0     0.0    B     1.0
4 2016-04-03     1.0     1.0     1.0    C     1.0
5 2016-04-04     0.0     1.0     1.0    B     1.0
6 2016-04-05     0.0     1.0     1.0    C     1.0
7 2016-04-06     0.0     0.0     2.0    C     2.0
8 2016-04-06     1.0     0.0     2.0    A     1.0

print(test)
        Date Type  N_occs
0 2016-04-01    A       1
1 2016-04-01    A       2
2 2016-04-02    A       3
3 2016-04-02    B       1
4 2016-04-03    C       1
5 2016-04-04    B       1
6 2016-04-05    C       1
7 2016-04-06    C       2
8 2016-04-06    A       1

我已经设法用了很多变通办法。如果有人有任何改进此代码的建议,他们将非常受欢迎,因为它最终将被专业地使用

test['Date'] = pd.to_datetime(test['Date'])

df = pd.get_dummies(test, columns=['Type']).set_index('Date')
df = df.apply(lambda x: x.rolling('2D').sum())
df['Type'] = test['Type'].values

# Prevent a double index error (dates are not unique)
df.reset_index(inplace=True)


type_cols = {'A': 'Type_A',
             'B': 'Type_B',
             'C': 'Type_C'}

for typ, col in type_cols.items():
    df.loc[df['Type'] == typ, 'N_occs'] = df[col]

test['N_occs'] = df['N_occs'].values
首先,我们提取虚拟编码,将索引设置为日期后,我们可以应用panda的滚动函数对这些计数求和。然后,我们根据类型选择适当的列,并将其复制到
N\u occs
。然后将其复制回原始数据帧。两个框架如下所示:

print(df)
        Date  Type_A  Type_B  Type_C Type  N_occs
0 2016-04-01     1.0     0.0     0.0    A     1.0
1 2016-04-01     2.0     0.0     0.0    A     2.0
2 2016-04-02     3.0     0.0     0.0    A     3.0
3 2016-04-02     3.0     1.0     0.0    B     1.0
4 2016-04-03     1.0     1.0     1.0    C     1.0
5 2016-04-04     0.0     1.0     1.0    B     1.0
6 2016-04-05     0.0     1.0     1.0    C     1.0
7 2016-04-06     0.0     0.0     2.0    C     2.0
8 2016-04-06     1.0     0.0     2.0    A     1.0

print(test)
        Date Type  N_occs
0 2016-04-01    A       1
1 2016-04-01    A       2
2 2016-04-02    A       3
3 2016-04-02    B       1
4 2016-04-03    C       1
5 2016-04-04    B       1
6 2016-04-05    C       1
7 2016-04-06    C       2
8 2016-04-06    A       1

以下是我的解决方案,灵感来自OP的解决方案。我没有使用“set_index”、“get_dummies”方法或显式循环

df["Date"]= pd.to_datetime(df.Date)

df2=df.groupby("Type") \
      .apply(lambda grp:grp.assign(Type=1) \
                           .rolling("2D",on="Date").sum())

                 Date  Type
    Type                   
    A    0 2016-04-01   1.0
         1 2016-04-01   2.0
         2 2016-04-02   3.0
         8 2016-04-06   1.0
    B    3 2016-04-02   1.0
         5 2016-04-04   1.0
    C    4 2016-04-03   1.0
         6 2016-04-05   1.0
         7 2016-04-06   2.0

df2= df2.reset_index(level=0,drop=True)

df["N_occs"]= df2["Type"]

                    Date Type  N_occs
            0 2016-04-01    A     1.0
            1 2016-04-01    A     2.0
            2 2016-04-02    A     3.0
            3 2016-04-02    B     1.0
            4 2016-04-03    C     1.0
            5 2016-04-04    B     1.0
            6 2016-04-05    C     1.0
            7 2016-04-06    C     2.0
            8 2016-04-06    A     1.0

以下是我的解决方案,灵感来自OP的解决方案。我没有使用“set_index”、“get_dummies”方法或显式循环

df["Date"]= pd.to_datetime(df.Date)

df2=df.groupby("Type") \
      .apply(lambda grp:grp.assign(Type=1) \
                           .rolling("2D",on="Date").sum())

                 Date  Type
    Type                   
    A    0 2016-04-01   1.0
         1 2016-04-01   2.0
         2 2016-04-02   3.0
         8 2016-04-06   1.0
    B    3 2016-04-02   1.0
         5 2016-04-04   1.0
    C    4 2016-04-03   1.0
         6 2016-04-05   1.0
         7 2016-04-06   2.0

df2= df2.reset_index(level=0,drop=True)

df["N_occs"]= df2["Type"]

                    Date Type  N_occs
            0 2016-04-01    A     1.0
            1 2016-04-01    A     2.0
            2 2016-04-02    A     3.0
            3 2016-04-02    B     1.0
            4 2016-04-03    C     1.0
            5 2016-04-04    B     1.0
            6 2016-04-05    C     1.0
            7 2016-04-06    C     2.0
            8 2016-04-06    A     1.0

过去两天发生的事件列不应该是[1,2,3,1,…],因为你不知道2016-04年之前会发生什么-01@Swedgin,说得好。我想把2放在前两行,因为2016-04-01发生了两个类型的“A”。然而,在现实中,这将被实时更新,所以你不知道在那一刻之后会发生多少类型的“A”。我会编辑它。过去两天发生的事件列不应该是[1,2,3,1,…],因为你不知道2016-04年之前会发生什么-01@Swedgin,说得好。我想把2放在前两行,因为2016-04-01发生了两个类型的“A”。然而,在现实中,这将被实时更新,所以你不知道在那一刻之后会发生多少类型的“A”。我将编辑它。这几乎可以工作,但它每两天重置一次。假设你在三天内有三个A型,N_occs列将是:1 2 1。如果你在我的解决方案中使用
freq='1D'
,你得到了正确的序列号吗?不,很遗憾我没有。我认为这种方法的缺点是,它会创建2天的静态组,而这些组应该是滚动的。我正在努力使用pd.rolling函数,但我的问题是如何在已经按类型分组的情况下实现这一点。这几乎可以工作,但它每两天重置一次。假设你在三天内有三个A型,N_occs列将是:1 2 1。如果你在我的解决方案中使用
freq='1D'
,你得到了正确的序列号吗?不,很遗憾我没有。我认为这种方法的缺点是,它会创建2天的静态组,而这些组应该是滚动的。我正在努力使用pd.rolling函数,但我的问题是如何在已经按类型分组的情况下实现这一点。