python - 如何将组切片到最近的第 n 个观察值
问题描述
我有一个看起来像这样的时间序列数据集:
Time ID X_Pos Y_Pos
1 1 150 300
2 1 160 310
3 1 156 500
4 2 300 439
5 2 200 500
6 3 500 320
7 3 400 230
8 3 500 540
9 3 450 600
10 3 400 600
我基本上需要将每个 ID 中的观察数四舍五入到最接近的第 n 倍数,在本例中,我将使用最接近的 2。这将产生一个如下所示的数据集:
Time ID X_Pos Y_Pos
1 1 150 300
2 1 160 310
4 2 300 439
5 2 200 500
6 3 500 320
7 3 400 230
8 3 500 540
9 3 450 600
如您所见,每个组中剩余的确切行数取决于组的初始大小,但始终保持为 2 的倍数。
通过下面的代码,我已经非常接近获得我需要的东西,但是我错过了最后一步(由问号指出):
grouped = data.groupby('ID')
timesteps = 2
def round_down(num, divisor):
return num - (num%divisor)
endSlice = pd.DataFrame(round_down(grouped.size(), timesteps)).reset_index()
slicedData = data.groupby('ID', as_index = False).apply(lambda x: x.iloc[0: ???????])
编辑 问题是,为了实现所需的数据集(即第二个数据集),我需要在问号所在的代码部分中添加什么,或者,是否有更有效的方法来实现这个数据集?
我认为问号所在的代码部分只需要引用每个 ID 的 endSlice 值,但我对 python 还很陌生,并且对这样的事情缺乏一些了解。
如果已在其他地方回答此问题,请提前感谢您的帮助和道歉。
解决方案
如果我理解正确,您可以这样做:
# Set the multiple that you want the size of each group to be:
n = 2
# Groupby ID, then apply .head() to get the size you want:
df.groupby('ID').apply(lambda x: x.head(len(x) - len(x) % n)).reset_index(drop=True)
Time ID X_Pos Y_Pos
0 1 1 150 300
1 2 1 160 310
2 4 2 300 439
3 5 2 200 500
4 6 3 500 320
5 7 3 400 230
6 8 3 500 540
7 9 3 450 600
请注意,这基本上等同于您尝试使用iloc
,并且不需要该round_down
功能:
df.groupby('ID').apply(lambda x: x.iloc[:len(x)-len(x)%n]).reset_index(drop=True)
这两个都将采用每组数据的开头,直到最接近的倍数n
。
相反,如果您希望每个组的随机数据(而不是数据的开头),但每个组的大小仍然是 的倍数n
,请使用sample
代替head
/ iloc
:
df.groupby('ID').apply(lambda x: x.sample(len(x) - len(x) % n)).reset_index(drop=True)
Time ID X_Pos Y_Pos
0 2 1 160 310
1 1 1 150 300
2 4 2 300 439
3 5 2 200 500
4 9 3 450 600
5 10 3 400 600
6 8 3 500 540
7 6 3 500 320
推荐阅读
- typescript - 打字稿:在没有明确创建判别式的情况下区分工会?
- excel - 基于 3 个单元格中较高者的组
- flutter - Flutter,如何准确实现原生admob?
- python - 使用 for 循环和 if/else 语句创建凯撒密码
- c# - C#多维列表
- r - 如何将df1中多列的元素与R中array1中的值匹配?
- ruby - 这些 'reverse' 和 'twist' 函数在 Ruby 中是如何工作的?(函数式编程)
- javascript - 如何将格式为“1969-03-07T05:00:00.000Z”的日期字符串转换为通常由 new Date() 提供的输出
- excel - 循环遍历单元格范围
- c++ - 宏是否可以扩展为在程序启动时仅执行一次的代码,而不管它使用了多少次?