【问题标题】:Grouping items by time-series bins in Python在 Python 中按时间序列箱对项目进行分组
【发布时间】:2014-08-09 13:20:33
【问题描述】:

我的数据看起来像:

[[datetime1, label1],
 [datetime2, label2],
 [datetime3, label3]]

标签是字符串。我有一个分箱参数 (delta),它是一个 datetime.timedelta。

我正在尝试做的事情:

  1. 想出一组由 delta 等间隔的日期时间箱。换句话说,下面, datetimebin2 - datetimebin1 = datetimebin3 - datetimebin2 = delta 。
  2. 将标签分箱到这些箱中。

所以我最终会得到类似的东西:

[[datetimebin1, [label1, label2],
 [datetimebin2, []],
 [datetimebin3, []],
 [datetimebin4, [label3]]

有人向我推荐了 pandas,但还没有找到我要找的东西。非常感谢任何帮助!

【问题讨论】:

  • 等间距是什么意思?
  • 并且 datetimebin1 是 datetime1 - datetime2 的 datetime 对象。例如?
  • 不一定。 datetimebin1 应该是数据中日期时间的最小值。 datetimebin2 将是 datetimebin1 + delta(其中 delta 是给定参数)。

标签: python binning


【解决方案1】:

我认为@DrV's 是正确答案,但我准备了一个示例,试图展示如何使用 Pandas 实现类似的目标:

import numpy
import pandas
import datetime
import time

# Binning delta

delta = datetime.timedelta(hours=1)

# Sample data

sample = [
    ['2014-08-09 16:30:00', 'label1'],
    ['2014-08-09 15:30:00', 'label2'],
    ['2014-08-09 14:30:00', 'label3'],
    ['2014-08-09 14:00:00', 'label4']
]

# Create dataframe and append UNIX timestamp column

df = pandas.DataFrame(sample)
df.columns = ['Datetime', 'Label']
df['Datetime'] = pandas.to_datetime(df['Datetime'])
df['UnixStamp'] = df['Datetime'].apply(lambda d: time.mktime(d.timetuple()))
df = df.set_index('Datetime')

# Calculate bins

bins = numpy.arange(min(df['UnixStamp']), max(df['UnixStamp']) + delta.seconds, delta.seconds)

# Group columns by datetime bin

def bin_from_tstamp(tstamp):

    diffs = [abs(tstamp - bin) for bin in bins]
    return bins[diffs.index(min(diffs))]

grouped = df.groupby(df['UnixStamp'].map(
    lambda t: datetime.datetime.fromtimestamp(bin_from_tstamp(t))
))

此时grouped 包含按日期时间箱分组的数据集。

以下是打印grouped.groups 的结果(其中键是日期时间箱,值是分组的日期时间):

{
    numpy.datetime64('2014-08-09T18:00:00.000000000+0200'): [
        Timestamp('2014-08-09 16:30:00')
    ], 
    numpy.datetime64('2014-08-09T17:00:00.000000000+0200'): [
        Timestamp('2014-08-09 15:30:00')
    ], 
    numpy.datetime64('2014-08-09T16:00:00.000000000+0200'): [
        Timestamp('2014-08-09 14:30:00'), 
        Timestamp('2014-08-09 14:00:00'
    ]
}

【讨论】:

  • 这很棒。我将检查哪个对我的数据(这个或 @DrV 的)更快,并且会更新。
【解决方案2】:

应该这样做:

# data: a lists of lists (length 2) of measurements
# res: resulting list of lists
# delta: time delta

# output list (will be a list of lists, as in the question

res = []
# end of first bin:
binstart = data[0][0]
res.append([binstart, []])

# iterate through the data item
for d in data:
    # if the data item belongs to this bin, append it into the bin
    if d[0] < binstart + delta:
        res[-1][1].append(d[1])
        continue

    # otherwise, create new empty bins until this data fits into a bin
    binstart += delta
    while d[0] > binstart + delta:
        res.append([binstart, [])
        binstart += delta

    # create a bin with the data
    res.append([binstart, [d[1]]])

【讨论】:

  • 我应该澄清一下数据不一定是排序的。不过很容易先对其进行排序;谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-14
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多