是否有等效于numpy.digitize的方法适用于pandas.IntervalIndex?

时间:2019-06-27 18:23:38

标签: pandas numpy

我需要将每月的每个小时与该小时所属月份的每月总计相匹配。

我通过了一个基于时间的monthly_totals的DataFrame(pandas.IntervalIndex)和另一个带有hours的DataFrame(pandas.DatetimeIndex)。更一般而言,我需要将一个DataFrame的索引与每个条目所属的另一个DataFrame的间隔进行匹配。

我有一个可行的解决方案,使用pandas.Series.apply,但是速度很慢。我看到numpy.digitize存在,并吓到我了,因为bins参数必须是一个数组,而不是IntervalIndex。

我的第一次尝试有效,但要花费大约1秒钟来处理长度为8760的DataFrame,如下所示:

def get_mock_montly_totals(self):
    start = '2018-07-01'
    end = '2019-07-01'
    hourly_rng = pd.date_range(start, end, freq='H')
    monthly_rng = pd.date_range(start, end, freq='MS')
    mock_series = pd.Series(1, index=hourly_rng)
    bins = (monthly_rng + pd.offsets.Day(pd.Timestamp(start).day - 1))
    cuts = pd.cut(mock_series.index, bins, right=False)
    groups = mock_series.groupby(cuts)
    monthly_totals = groups.sum()
    return monthly_totals

def get_interval_value(self, frame, key):
    try:
        return frame.iloc[frame.index.get_loc(key)]
    except KeyError:
        return np.nan

result = api.get_secret_data().resample('H').asfreq()
hours = result.index.to_series()
monthly_totals = self.get_mock_montly_totals()

# This line takes over a second to run, which is too slow.
result['monthly_totals'] = hours.apply(
    lambda h: self.get_interval_value(monthly_totals, h))

monthly_totals如下所示:

[2018-07-01, 2018-08-01)    744
[2018-08-01, 2018-09-01)    744
[2018-09-01, 2018-10-01)    720
[2018-10-01, 2018-11-01)    744
[2018-11-01, 2018-12-01)    720
[2018-12-01, 2019-01-01)    744
[2019-01-01, 2019-02-01)    744
[2019-02-01, 2019-03-01)    672
[2019-03-01, 2019-04-01)    744
[2019-04-01, 2019-05-01)    720
[2019-05-01, 2019-06-01)    744
[2019-06-01, 2019-07-01)    720
dtype: int64

hours如下:

time
2018-06-27 00:00:00-10:00   2018-06-27 10:00:00
...
2019-06-24 21:00:00-10:00   2019-06-25 07:00:00

输出result['monthly_totals']应该看起来像:

time
2018-06-27 00:00:00-10:00      NaN
...
2019-06-24 20:00:00-10:00      720
2019-06-24 21:00:00-10:00      720

同样,我的解决方案有效,但是对apply的调用似乎使它变得很慢。因此,我真的希望获得一些帮助,以寻求更清洁的解决方案。谢谢!

0 个答案:

没有答案