Python:如何获取在某个位置花费时间的分布

0 投票
2 回答
683 浏览
提问于 2025-04-17 19:53

我有一个大数据文件,里面记录了一些用户的位置情况。格式如下:

   User      TimeStamp            Lat        Long
     A   2013-03-01 19:55:00     45.4565    65.6783
     A   2013-03-01 01:40:00     46.3121    -12.3456
     A   2013-03-02 11:25:00     23.1234    -85.3456
     A   2013-03-05 05:00:00     15.4565    32.1234
        ......   

     C   2013-03-01 19:55:00     44.4565    35.6783
     C   2013-03-03 11:20:00     42.3121    -22.3456
     C   2013-03-03 11:25:00     42.3121    -22.3456
     C   2013-03-03 11:30:00     16.4565    22.1234
     C   2013-03-03 11:50:00     42.3121    -22.3456
     C   2013-03-03 11:55:00     19.4565    -25.1234
        ......  

这些时间戳的意思是,每一行代表在5分钟的时间间隔内的位置。这些数据是为期一周的。

现在,我想做的是获取一个简单的分布图(直方图),显示每个用户每天在每个位置上花费的时间,覆盖整个一周的时间。所以,这将是一个从0点到24点的图,展示每个用户每天在每个位置上花费的时间。

第二个需求和第一个类似,但这次我不想考虑用户每天的总时间,而是只考虑连续的时间。例如,对于用户C,我会把第2行和第3行一起算作10分钟的时间段,但第5行他回到同一个地方就算作一个单独的5分钟时间段。

我该如何用Python来实现这个呢?我还是个新手,有点卡住了。我想我可以把时间戳拆分成天、小时、分钟和秒,以便计算每天的时间。但之后我就不知道该怎么做了。

2 个回答

0

你可以像这样制作一个热力图:

import numpy as np
import pandas as pd
import io
import matplotlib.pyplot as plt

content = '''\
   User      TimeStamp            Lat        Long
     A   2013-03-01 19:55:00     45.4565    65.6783
     A   2013-03-01 01:40:00     46.3121    -12.3456
     A   2013-03-02 11:25:00     23.1234    -85.3456
     A   2013-03-05 05:00:00     15.4565    32.1234
     C   2013-03-01 19:55:00     44.4565    35.6783
     C   2013-03-03 11:20:00     42.3121    -22.3456
     C   2013-03-03 11:25:00     42.3121    -22.3456
     C   2013-03-03 11:30:00     16.4565    22.1234
     C   2013-03-03 11:50:00     42.3121    -22.3456
     C   2013-03-03 11:55:00     19.4565    -25.1234
'''

df = pd.read_table(io.BytesIO(content), sep='\s+', parse_dates=True, index_col=[1])
fig, ax = plt.subplots(df['User'].nunique())
for i, (user, grp) in enumerate(df.groupby('User')):
    xedges = np.linspace(grp['Long'].min(), grp['Long'].max(), 5)
    yedges = np.linspace(grp['Lat'].min(), grp['Lat'].max(), 7)        
    hist, xedges, yedges = np.histogram2d(
        grp['Long'], grp['Lat'], (xedges, yedges), normed=False)
    hist = hist.T
    print(hist)
    ax[i].pcolormesh(hist, cmap=plt.get_cmap('jet'))
    ax[i].set_xticks(np.arange(hist.shape[1]+1), minor=False)
    ax[i].set_xticklabels(map('{:0.2f}'.format, xedges), minor=False)
    ax[i].set_yticks(np.arange(hist.shape[0]+1), minor=False)
    ax[i].set_yticklabels(map('{:0.2f}'.format, yedges), minor=False)
    ax[i].invert_yaxis()
    ax[i].set_xlim(0, hist.shape[1])
    ax[i].set_ylim(0, hist.shape[0])
    ax[i].set_title(user)
plt.show()

在这里输入图片描述

1

为了收集数据:

在第一部分(我们还没有把时间戳“合并”在一起的时候),需要维护一个记录

(纬度, 经度) -> 花费的时间的映射。

处理每个时间戳时,增加相应的映射条目的时间。

在第二部分:

首先按用户排序时间戳,然后再按时间排序。现在你可以用两个“指针”来遍历这个列表,一个指向开始,另一个指向连续时间段的结束。

在你的映射中增加一个第三个“维度”,这个维度可以对应于连续时间段的开始。

也就是说:

(纬度, 经度, 时间段开始) -> 花费的时间

这样,你就可以把所有在一个连续时间段内的时间戳加到相应的映射条目中。

可视化是另一个难题:我对如何处理它完全没有头绪。

撰写回答