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