如何使用DateTime对Pandas DataFrame进行分区

3
我正在编写一个Python脚本来导入数码相机中的图片,并使用Pandas来帮助处理进来的图像的簿记。我使用EXIF数据为单个图像打上标签,例如相机型号、图像模式、图像格式以及相机拍摄图像的时间戳。这些数据用于将图像分类到目录结构中。我遇到的问题是如何使用Pandas根据在半小时内的一组时间戳对图像进行分组。举个例子,假设我有六张图片,其中三张在九分钟内拍摄,然后另外三张也在九分钟内拍摄,但是时间比前面晚一个小时。
import pandas
import datetime    
rawdata = [{'filename': 'image_1.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 19, 14, 16, 152847)},
 {'filename': 'image_2.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 19, 17, 16, 152847)},
 {'filename': 'image_3.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 19, 20, 16, 152847)},
 {'filename': 'image_4.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 20, 14, 16, 152847)},
 {'filename': 'image_5.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 20, 17, 16, 152847)},
 {'filename': 'image_6.jpg',
  'timestamp': datetime.datetime(2014, 11, 13, 20, 20, 16, 152847)}]
df = pandas.DataFrame(rawdata)

有没有一种自动分区DataFrame的方法,以半小时为阈值,使得我可以在一个DataFrame中有image_1,image_2和image_3,在第二个DataFrame中有image_4,image_5和image_6?

你想通过组之间的空格来分割它们吗?你已经尝试了哪些解决方案,为什么它们不够满意? - wwii
1个回答

8

如果我理解正确,一种方法是使用diff-compare-cumsum习语来获取集群编号,然后可以使用它来进行groupby

>>> df = df.sort("timestamp")
>>> cluster = (df["timestamp"].diff() > pd.Timedelta(minutes=30)).cumsum()
>>> dfs = [v for k,v in df.groupby(cluster)]
>>> for clust in dfs:
...     print(clust)
...     
      filename                  timestamp
0  image_1.jpg 2014-11-13 19:14:16.152847
1  image_2.jpg 2014-11-13 19:17:16.152847
2  image_3.jpg 2014-11-13 19:20:16.152847
      filename                  timestamp
3  image_4.jpg 2014-11-13 20:14:16.152847
4  image_5.jpg 2014-11-13 20:17:16.152847
5  image_6.jpg 2014-11-13 20:20:16.152847

这个方法有效的原因是False等于0,True等于1。所以如果我们对每次发现新聚类时变为1的内容进行累加,就可以得到我们想要的id值:
>>> df["timestamp"].diff()
0        NaT
1   00:03:00
2   00:03:00
3   00:54:00
4   00:03:00
5   00:03:00
Name: timestamp, dtype: timedelta64[ns]
>>> df["timestamp"].diff() > pd.Timedelta(minutes=30)
0    False
1    False
2    False
3     True
4    False
5    False
Name: timestamp, dtype: bool
>>> (df["timestamp"].diff() > pd.Timedelta(minutes=30)).cumsum()
0    0
1    0
2    0
3    1
4    1
5    1
Name: timestamp, dtype: int64

谢谢您的快速回复,这正是我所寻找的! - vishnubob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接