熊猫数据帧的持续时间扩展为分钟数据

时间:2020-07-15 05:18:56

标签: python pandas time aggregate duration

我正在接收包含有效时间的“开始时间”和“持续时间”的数据。当我需要在多天的指定时间范围内进行计算时,这很难解决。我想将此数据细分为一些细微的数据,以使将来的计算更加容易。请参阅示例以更好地理解。

我当前拥有的数据:

data = {'StartTime':['2018-12-30 12:45:00+11:00','2018-12-31 16:48:00+11:00','2019-01-01 04:36:00+11:00','2019-01-01 19:27:00+11:00','2019-01-02 05:13:00+11:00'],
        'Duration':[1,1,3,1,2],
        'Site':['1','2','3','4','5']    
}

df = pd.DataFrame(data)
df['StartTime'] = pd.to_datetime(df['StartTime']).dt.tz_localize('utc').dt.tz_convert('Australia/Melbourne')

我想拥有的东西:

data_expected = {'Time':['2018-12-30 12:45:00+11:00','2018-12-31 16:48:00+11:00','2019-01-01 04:36:00+11:00','2019-01-01 04:37:00+11:00','2019-01-01 19:27:00+11:00','2019-01-02 05:13:00+11:00','2019-01-02 05:14:00+11:00'],
        'Duration':[1,1,1,1,1,1,1],
        'Site':['1','2','3','3','4','5','5']    
}

df_expected = pd.DataFrame(data_expected)
df_expected['Time'] = pd.to_datetime(df_expected['Time']).dt.tz_localize('utc').dt.tz_convert('Australia/Melbourne')

我想看看是否有人对此问题有很好的解决方案。实际上,对于持续时间大于1分钟的每一分钟,我需要将持续时间> 1的数据行与时间+1分钟进行复制。有没有一种方法可以创建一个新的数据框呢?

********编辑********

响应@DavidErickson的回答。将其放在此处是因为我无法在评论中添加图片。我遇到了麻烦。 df1是原始数据帧的子集。应用提供的代码后,df2为df1。您可以看到添加到索引635的时间不正确。 Comparison dataframes

2 个答案:

答案 0 :(得分:2)

我认为您可能还想解决Duration > 2的用例。

对于修改后的给定输入:

data = {'StartTime':['2018-12-30 12:45:00+11:00','2018-12-31 16:48:00+11:00','2019-01-01 04:36:00+11:00','2019-01-01 19:27:00+11:00','2019-01-02 05:13:00+11:00'],
        'Duration':[1,1,3,1,2],
        'Site':['1','2','3','4','5']    
}

df = pd.DataFrame(data)
df['StartTime'] = pd.to_datetime(df['StartTime'])

此代码应能解决问题:

df['offset'] = df['Duration'].apply(lambda x: list(range(x)))
df = df.explode('offset')
df['offset'] = df['offset'].apply(lambda x: pd.Timedelta(x, unit='T'))
df['StartTime'] += df['offset']
df["Duration"] = 1

基本上,其工作原理如下:

  • 基于Duration值创建一个整数列表;
  • 使用连续的整数偏移量复制行(explode);
  • 将整数偏移量转换为timedelta偏移量;
  • 执行datetime算术并重置“持续时间”字段。

结果大约是:

                  StartTime  Duration Site   offset
0 2018-12-30 12:45:00+11:00         1    1 00:00:00
1 2018-12-31 16:48:00+11:00         1    2 00:00:00
2 2019-01-01 04:36:00+11:00         1    3 00:00:00
2 2019-01-01 04:37:00+11:00         1    3 00:01:00
2 2019-01-01 04:38:00+11:00         1    3 00:02:00
3 2019-01-01 19:27:00+11:00         1    4 00:00:00
4 2019-01-02 05:13:00+11:00         1    5 00:00:00
4 2019-01-02 05:14:00+11:00         1    5 00:01:00

答案 1 :(得分:0)

根据set -o pipefail kubectl api-resources --verbs=list --namespaced -o name \ | xargs -n 1 kubectl get --ignore-not-found -n staging -o json \ | jq '.items[]| .kind + "/" + .metadata.name | error' 列使用df.index.repeat添加相关的行数。然后使用Duration.groupby创建一个掩码,在基础时间之上添加适当的分钟数。

输入:

cumcount

代码:

data = {'StartTime':['2018-12-30 12:45:00+11:00','2018-12-31 16:48:00+11:00','2019-01-01 04:36:00+11:00','2019-01-01 19:27:00+11:00','2019-01-02 05:13:00+11:00'],
        'Duration':[1,1,2,1,2],
        'Site':['1','2','3','4','5']    
}
df = pd.DataFrame(data)
df['StartTime'] = pd.to_datetime(df['StartTime'])

输出:

df = df.loc[df.index.repeat(df['Duration'])]
mask = df.groupby('Site').cumcount()
df['StartTime'] = df['StartTime'] + pd.to_timedelta(mask, unit='m')
df = df.append(df).sort_values('StartTime').assign(Duration=1).drop_duplicates()
df

如果遇到内存问题,也可以尝试使用 StartTime Duration Site 0 2018-12-30 12:45:00+11:00 1 1 1 2018-12-31 16:48:00+11:00 1 2 2 2019-01-01 04:36:00+11:00 1 3 2 2019-01-01 04:37:00+11:00 1 3 2 2019-01-01 04:38:00+11:00 1 3 3 2019-01-01 19:27:00+11:00 1 4 4 2019-01-02 05:13:00+11:00 1 5 4 2019-01-02 05:14:00+11:00 1 5 。我已经包含@jlandercy的pandas答案,并更改为dask的语法,因为我不确定pandas操作dask是否可以与index.repeat一起使用。这是有关功能/操作的文档。我会研究代码https://docs.dask.org/en/latest/dataframe-api.html#dask.dataframe.read_sql_table中的内容:

dask