我有一个DataFrame,其中包含一个马拉松比赛的结果,其中每一行代表一个跑步者,而列包括像"开始时间" (timedelta),"净时间" (timedelta)和Place(int)。开始时间与净时间的散点图可以很容易地在视觉上识别比赛中不同的起始畜栏(加热):
我想分别分析每个热量,但我无法弄清楚如何将它们分开。比赛中约有20,000名参赛者。起始时间间隔不一致,给定畜栏中的跑步者数量也不一致
我用来组织数据的代码的要点: https://gist.github.com/kellbot/1bab3ae83d7b80ee382a
包含约500条结果的CSV: https://github.com/kellbot/raceresults/blob/master/Full/B.csv
答案 0 :(得分:2)
如果我理解正确,那么您正在寻求一种通过算法将Start Num值聚合成不同热量的方法。这是一维分类/聚类问题。
快速解决方案是使用众多Jenks自然中断脚本之一。我之前使用过drewda的版本:
https://gist.github.com/drewda/1299198
从情节的检查中,我们知道有16次加热。所以你可以先验地选择16的类数。
k = jenks.getJenksBreaks(full['Start Num'].tolist(),16)
ax = full.plot(kind='scatter', x='Start Num', y='Net Time Sec', figsize=(15,15))
[plt.axvline(x) for x in k]
从您的示例数据中,我们看到它做得非常好,但观察的稀疏性无法确定最小的Start Num区间之间的中断:
答案 1 :(得分:2)
你可以通过很多方法做到这一点(包括在其上投掷scipy的k-means),但是简单的检查可以清楚地知道加热之间至少有60秒的时间。因此,我们需要做的就是对开始时间进行排序,找到60s的间隙,每次我们找到间隙时都会分配一个新的热量数。
使用diff
- compare - cumsum
模式:
starts = df["Start Time"].copy()
starts.sort()
dt = starts.diff()
heat = (dt > pd.Timedelta(seconds=60)).cumsum()
heat = heat.sort_index()
正确地拾取16个(明显的)组,这里用热数字着色: