如何将组切割到最近的第n次观察

时间:2018-06-11 23:01:36

标签: python pandas pandas-groupby

我有一个时间序列数据集,如下所示:

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很新,而且缺乏对此类内容的一些了解。

如果在其他地方得到解答,请提前感谢任何帮助和道歉。

1 个答案:

答案 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