我有一个时间序列数据集,如下所示:
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很新,而且缺乏对此类内容的一些了解。
如果在其他地方得到解答,请提前感谢任何帮助和道歉。
答案 0 :(得分:0)
如果我理解正确,你可以这样做:
# 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