在 python 中的分组数据框中查找差异
Finding difference within grouped dataframe in python
我有这个数据框:
Value ID
Timestamp
-----------------------------------------
2018-07-03 02:19:28 45 111
2018-07-03 02:19:29 36 111
2018-07-03 02:19:30 64 111
2018-07-03 02:19:31 35 111
2018-07-03 02:19:32 22 111
...
2018-07-03 03:43:14 35 232
2018-07-03 03:43:15 44 232
2018-07-03 03:43:16 64 232
2018-07-03 03:43:17 44 232
2018-07-03 03:43:18 64 232
...
2018-07-03 05:20:28 35 555
2018-07-03 05:21:28 44 555
2018-07-03 05:22:28 75 555
2018-07-03 05:19:28 84 555
2018-07-03 05:19:28 35 555
...
在这里,每个 ID 代表整个数据集的不同“子集”。所以ID 111是它自己的时间序列数据集,232是它自己的时间序列数据集,555是它自己的时间序列数据集,还有更多没有显示。我想做的是,使用 python,针对这些数据子集中的每一个,根据“值”列中的值找到峰谷的数量,然后将其附加到原始数据框,如下所示:
Value ID Curve_Changes
Timestamp
------------------------------------------------------------
2018-07-03 02:19:28 45 111 4
2018-07-03 02:19:29 36 111 4
2018-07-03 02:19:30 64 111 4
2018-07-03 02:19:31 35 111 4
2018-07-03 02:19:32 22 111 4
...
2018-07-03 03:43:14 35 232 9
2018-07-03 03:43:15 44 232 9
2018-07-03 03:43:16 64 232 9
2018-07-03 03:43:17 44 232 9
2018-07-03 03:43:18 64 232 9
...
2018-07-03 05:20:28 35 555 12
2018-07-03 05:21:28 44 555 12
2018-07-03 05:22:28 75 555 12
2018-07-03 05:19:28 84 555 12
2018-07-03 05:19:28 35 555 12
...
基于这个理想的输出示例数据框,这意味着如果您要绘制与 ID 111 对应的时间序列数据子集,您将看到 4 条曲线变化(无论是峰还是谷),如果您是绘制ID 232对应的时间序列数据子集,会看到9条曲线变化(波峰波谷)等
我正在尝试使用此代码来查找波峰和波谷的数量:
slopes = df["Value"].diff().bfill()
signs = slopes > 0
changes = signs.astype(float).diff(periods=-1).fillna(0)
num_changes = changes.abs().sum()
其中 num_changes
是我想要的曲线变化数。我能够让它在整个数据帧上工作,但我很困惑如何让它对每个单独的时间序列数据子集起作用,以便生成我上面显示的理想输出示例数据帧。我不确定这应该如何组织,但我认为这将是一个 .groupby()
类型的任务,我认为我需要对“ID”列进行“分组”,但我不确定。如何按数据子集按数据框分组并找到每个子集的曲线变化数并将其与原始数据框匹配?
在此处使用 GroupBy.transform
将每组的解决方案应用于新列:
def f(x):
#for debug
print (x)
slopes = x.diff().bfill()
#for debug
print (slopes)
signs = slopes > 0
changes = signs.astype(float).diff(periods=-1).fillna(0)
return changes.abs().sum()
df['Curve_Changes'] = df.groupby('ID')['Value'].transform(f)
我有这个数据框:
Value ID
Timestamp
-----------------------------------------
2018-07-03 02:19:28 45 111
2018-07-03 02:19:29 36 111
2018-07-03 02:19:30 64 111
2018-07-03 02:19:31 35 111
2018-07-03 02:19:32 22 111
...
2018-07-03 03:43:14 35 232
2018-07-03 03:43:15 44 232
2018-07-03 03:43:16 64 232
2018-07-03 03:43:17 44 232
2018-07-03 03:43:18 64 232
...
2018-07-03 05:20:28 35 555
2018-07-03 05:21:28 44 555
2018-07-03 05:22:28 75 555
2018-07-03 05:19:28 84 555
2018-07-03 05:19:28 35 555
...
在这里,每个 ID 代表整个数据集的不同“子集”。所以ID 111是它自己的时间序列数据集,232是它自己的时间序列数据集,555是它自己的时间序列数据集,还有更多没有显示。我想做的是,使用 python,针对这些数据子集中的每一个,根据“值”列中的值找到峰谷的数量,然后将其附加到原始数据框,如下所示:
Value ID Curve_Changes
Timestamp
------------------------------------------------------------
2018-07-03 02:19:28 45 111 4
2018-07-03 02:19:29 36 111 4
2018-07-03 02:19:30 64 111 4
2018-07-03 02:19:31 35 111 4
2018-07-03 02:19:32 22 111 4
...
2018-07-03 03:43:14 35 232 9
2018-07-03 03:43:15 44 232 9
2018-07-03 03:43:16 64 232 9
2018-07-03 03:43:17 44 232 9
2018-07-03 03:43:18 64 232 9
...
2018-07-03 05:20:28 35 555 12
2018-07-03 05:21:28 44 555 12
2018-07-03 05:22:28 75 555 12
2018-07-03 05:19:28 84 555 12
2018-07-03 05:19:28 35 555 12
...
基于这个理想的输出示例数据框,这意味着如果您要绘制与 ID 111 对应的时间序列数据子集,您将看到 4 条曲线变化(无论是峰还是谷),如果您是绘制ID 232对应的时间序列数据子集,会看到9条曲线变化(波峰波谷)等
我正在尝试使用此代码来查找波峰和波谷的数量:
slopes = df["Value"].diff().bfill()
signs = slopes > 0
changes = signs.astype(float).diff(periods=-1).fillna(0)
num_changes = changes.abs().sum()
其中 num_changes
是我想要的曲线变化数。我能够让它在整个数据帧上工作,但我很困惑如何让它对每个单独的时间序列数据子集起作用,以便生成我上面显示的理想输出示例数据帧。我不确定这应该如何组织,但我认为这将是一个 .groupby()
类型的任务,我认为我需要对“ID”列进行“分组”,但我不确定。如何按数据子集按数据框分组并找到每个子集的曲线变化数并将其与原始数据框匹配?
在此处使用 GroupBy.transform
将每组的解决方案应用于新列:
def f(x):
#for debug
print (x)
slopes = x.diff().bfill()
#for debug
print (slopes)
signs = slopes > 0
changes = signs.astype(float).diff(periods=-1).fillna(0)
return changes.abs().sum()
df['Curve_Changes'] = df.groupby('ID')['Value'].transform(f)