首页 > 解决方案 > 按 Pandas 中不同时间范围的列表分组

问题描述

编辑:更改示例以使用 Timedelta 索引。

我有一个不同时间范围的 DataFrame,它们代表我的主 DataFrame 中的索引。例如:

ranges = pd.DataFrame(data=np.array([[1,10,20],[3,15,30]]).T, columns=["Start","Stop"])
ranges = ranges.apply(pd.to_timedelta, unit="s")
ranges
            Start            Stop
0 0 days 00:00:01 0 days 00:00:03
1 0 days 00:00:10 0 days 00:00:15
2 0 days 00:00:20 0 days 00:00:30

my_data= pd.DataFrame(data=list(range(0,40*5,5)), columns=["data"])
my_data.index = pd.to_timedelta(my_data.index, unit="s")

我想为范围内的每个时间范围计算 my_data 中数据的平均值。我怎样才能做到这一点?

一种选择如下:

ranges.apply(lambda row: my_data.loc[row["Start"]:row["Stop"]].iloc[:-1].mean(), axis=1)
    data
0    7.5
1   60.0
2  122.5

但是我们可以在没有应用的情况下做到这一点吗?

标签: pythonpandas

解决方案


这是处理它的一种方法:

生成时间增量并连接成一个块:

# note the use of closed='left' (`Stop` is not included in the build)
timedelta = [pd.timedelta_range(a,b, closed='left', freq='1s')
             for a, b in zip(ranges.Start, ranges.Stop)]

timedelta = timedelta[0].append(timedelta[1:])

获取将用于 groupby 和聚合的分组:

counts = ranges.Stop.sub(ranges.Start).dt.seconds
counts = np.arange(counts.size).repeat(counts)

分组和聚合:

my_data.loc[timedelta].groupby(counts).mean()

    data
0    7.5
1   60.0
2  122.5 

推荐阅读