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函数,但我的问题是如何在已经按类型分组的情况下实现这一点。