Python 熊猫:按分组并选择间隔均匀的行

Python 熊猫:按分组并选择间隔均匀的行,python,pandas,Python,Pandas,下面是我的datafame,按视频ID时间戳排序(为了简单起见,时间戳列已被删除) 每个cameraId有4-100个视频。我需要为每一个摄像机选择4个视频,并且间隔均匀。例如,如果一个cameraId有100个视频,我应该选择视频[0,33,66,99] 这是我的方法,选择第一个和最后一个视频,然后随机抽样中间的2个 first_video = df.drop_duplicates(['cameraId'], keep='first') last_video = df.drop_duplica

下面是我的datafame,按视频ID时间戳排序(为了简单起见,时间戳列已被删除)

每个cameraId有4-100个视频。我需要为每一个摄像机选择4个视频,并且间隔均匀。例如,如果一个cameraId有100个视频,我应该选择视频[0,33,66,99]

这是我的方法,选择第一个和最后一个视频,然后随机抽样中间的2个

first_video = df.drop_duplicates(['cameraId'], keep='first')
last_video = df.drop_duplicates(['cameraId'], keep='last')
middle_videos = df.groupby(['cameraId']).apply(lambda x: x.sample(2, random_state=seed)).reset_index(drop=True)
df = pd.concat([first_video, middle_videos, last_video])
中间的视频通常间隔不均匀,这就是我被卡住的地方


每个摄像头的输出应为4行RAID

如果您总是想要这2个百分位,一种快速的方法是只设置一些小函数,您可以在这些函数上进行聚合:

In [44]: df = pd.DataFrame({
    ...:     'id': [1] * 10 + [2] * 10 + [3] * 20,
    ...:     'file': ['f{}'.format(i) for i in range(10)] +
    ...:             ['f{}'.format(i) for i in range(10,20)] +
    ...:             ['f{}'.format(i) for i in range(20,40)]
    ...: })

In [45]: def pct33(s):
    ...:     return s.iloc[int(len(s) * .33)]
    ...:

In [46]: def pct66(s):
    ...:     return s.iloc[int(len(s) * .66)]
    ...:

In [47]: df.groupby('id').agg({'file': ['first', pct33, pct66, 'last']}).unstack()
Out[47]:
             id
file  first  1      f0
             2     f10
             3     f20
      pct33  1      f3
             2     f13
             3     f26
      pct66  1      f6
             2     f16
             3     f33
      last   1      f9
             2     f19
             3     f39
dtype: object

您也可以根据需要删除额外的索引级别或稍后使用它们。

添加上述示例的输出。数据帧有100k行,每个摄像头的输出将为4行,这将很难显示。因此,请使用一个
cameraId
提供数据,例如。,10个视频。哇,我不知道你可以像那样先打
再打
再打
最后一个
。我想知道的是,如果我想要10个视频均匀分布,我是否必须先编写8个pct函数(
first,pct2,pct3,…,pct8,pct9 last
),对于更多的文件,你可以做类似于
df.groupby(“id”).apply(lambda x:x.iloc[[int(len(x)*I/10)的操作,比如为范围(10)])
虽然这可能需要一些调整。实际上,可能只需将范围(11)中的i的内部部分更改为
int((len(x)-1)*i/10)
即可满足您的需要
In [44]: df = pd.DataFrame({
    ...:     'id': [1] * 10 + [2] * 10 + [3] * 20,
    ...:     'file': ['f{}'.format(i) for i in range(10)] +
    ...:             ['f{}'.format(i) for i in range(10,20)] +
    ...:             ['f{}'.format(i) for i in range(20,40)]
    ...: })

In [45]: def pct33(s):
    ...:     return s.iloc[int(len(s) * .33)]
    ...:

In [46]: def pct66(s):
    ...:     return s.iloc[int(len(s) * .66)]
    ...:

In [47]: df.groupby('id').agg({'file': ['first', pct33, pct66, 'last']}).unstack()
Out[47]:
             id
file  first  1      f0
             2     f10
             3     f20
      pct33  1      f3
             2     f13
             3     f26
      pct66  1      f6
             2     f16
             3     f33
      last   1      f9
             2     f19
             3     f39
dtype: object