pandas 将时间戳分桶到 TimeGrouper 频率组中
pandas bucket timestamp into TimeGrouper frequency group
我在 pandas 中有一个带有 DateTime 索引的数据框。
当使用 time grouper 对其进行分组时:pd.Grouper(freq='360Min')
,如何将此结果加入到原始时间戳中?
IE。 equijoin timestamp=bucket 不起作用?
有方便的功能吗?
应该使用 asof
连接吗?
或者我是否必须手动提取小时数然后尝试匹配它?
示例:
来源
import pandas as pd
df = pd.DataFrame(
{
"Publish date": [
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-09"),
pd.Timestamp("2000-01-16")
],
"ID": [0, 1, 2, 3],
"Price": [10, 20, 30, 40]
}
)
给出:
Publish date ID Price
0 2000-01-02 0 10
1 2000-01-02 1 20
2 2000-01-09 2 30
3 2000-01-16 3 40
我想以任意频率(不仅是月、日、小时)执行聚合,假设 1
month.
agg_result = df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median]).reset_index()
agg_result.columns = ['_'.join(col).strip() for col in agg_result.columns.values]
agg_result.columns = ['Publish date month', 'ID_mean', 'ID_median', 'Price_mean', 'Price_median']
print(agg_result)
Publish date month ID_mean ID_median Price_mean Price_median
0 2000-01-31 1.5 1.5 25 25
如何确保等值连接再次起作用? IE。使用相同的任意频率将原始时间戳转换为拟合桶?
即在例子的代码中描述,我如何得到:
agg_result['Publish date month'] = agg_result['Publish date'].apply(magic transform to same frequency bucket)
df.merge(agg_result, on['Publish date month'])
要工作,即将转换定义到正确的存储桶?
编辑:
确定每组对应原始值的最简单方法应该是:
gb = df.groupby(pd.Grouper(key="Publish date", freq="1M"))
dict(list(gb['Publish date']))
然后您可以使用它来将任何信息连接回原始 table。
你能加入两个中间列吗?
df['Publish date'].dt.month
和
df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median]).index.month
像这样
results = df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median])
results.columns = ['-'.join(col[::-1]).strip() for col in results.columns]
df['month'] = df['Publish date'].dt.month
results['month'] = results.index.month
results.merge(df)
我会使用 Groupby.transform
方法:
import pandas as pd
df = pd.DataFrame(
{
"Publish date": [
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-09"),
pd.Timestamp("2000-01-16")
],
"ID": [0, 1, 2, 3],
"Price": [10, 20, 30, 40]
}
)
g = df.groupby(pd.Grouper(key="Publish date", freq="1M"))
(
df.join(g.transform('mean'), rsuffix='_mean')
.join(g.transform('median'), rsuffix='_median')
)
还有那个 returns:
Publish date ID Price ID_mean Price_mean ID_median Price_median
0 2000-01-02 0 10 1.5 25 1.5 25
1 2000-01-02 1 20 1.5 25 1.5 25
2 2000-01-09 2 30 1.5 25 1.5 25
3 2000-01-16 3 40 1.5 25 1.5 25
您也可以使用 pandas.concat
代替 DataFrame.join
:
methods = ['mean', 'median', 'std', 'min', 'max']
pd.concat([
df, *[g.transform(m).add_suffix(f'_{m}') for m in methods]
], axis='columns')
这给你:
Publish date ID Price ID_mean Price_mean ID_median Price_median ID_std Price_std ID_min Price_min ID_max Price_max
0 2000-01-02 0 10 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
1 2000-01-02 1 20 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
2 2000-01-09 2 30 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
3 2000-01-16 3 40 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
我在 pandas 中有一个带有 DateTime 索引的数据框。
当使用 time grouper 对其进行分组时:pd.Grouper(freq='360Min')
,如何将此结果加入到原始时间戳中?
IE。 equijoin timestamp=bucket 不起作用?
有方便的功能吗?
应该使用 asof
连接吗?
或者我是否必须手动提取小时数然后尝试匹配它?
示例:
来源
import pandas as pd
df = pd.DataFrame(
{
"Publish date": [
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-09"),
pd.Timestamp("2000-01-16")
],
"ID": [0, 1, 2, 3],
"Price": [10, 20, 30, 40]
}
)
给出:
Publish date ID Price
0 2000-01-02 0 10
1 2000-01-02 1 20
2 2000-01-09 2 30
3 2000-01-16 3 40
我想以任意频率(不仅是月、日、小时)执行聚合,假设 1
month.
agg_result = df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median]).reset_index()
agg_result.columns = ['_'.join(col).strip() for col in agg_result.columns.values]
agg_result.columns = ['Publish date month', 'ID_mean', 'ID_median', 'Price_mean', 'Price_median']
print(agg_result)
Publish date month ID_mean ID_median Price_mean Price_median
0 2000-01-31 1.5 1.5 25 25
如何确保等值连接再次起作用? IE。使用相同的任意频率将原始时间戳转换为拟合桶?
即在例子的代码中描述,我如何得到:
agg_result['Publish date month'] = agg_result['Publish date'].apply(magic transform to same frequency bucket)
df.merge(agg_result, on['Publish date month'])
要工作,即将转换定义到正确的存储桶?
编辑:
确定每组对应原始值的最简单方法应该是:
gb = df.groupby(pd.Grouper(key="Publish date", freq="1M"))
dict(list(gb['Publish date']))
然后您可以使用它来将任何信息连接回原始 table。
你能加入两个中间列吗?
df['Publish date'].dt.month
和
df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median]).index.month
像这样
results = df.groupby(pd.Grouper(key="Publish date", freq="1M")).agg([pd.Series.mean, pd.Series.median])
results.columns = ['-'.join(col[::-1]).strip() for col in results.columns]
df['month'] = df['Publish date'].dt.month
results['month'] = results.index.month
results.merge(df)
我会使用 Groupby.transform
方法:
import pandas as pd
df = pd.DataFrame(
{
"Publish date": [
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-09"),
pd.Timestamp("2000-01-16")
],
"ID": [0, 1, 2, 3],
"Price": [10, 20, 30, 40]
}
)
g = df.groupby(pd.Grouper(key="Publish date", freq="1M"))
(
df.join(g.transform('mean'), rsuffix='_mean')
.join(g.transform('median'), rsuffix='_median')
)
还有那个 returns:
Publish date ID Price ID_mean Price_mean ID_median Price_median
0 2000-01-02 0 10 1.5 25 1.5 25
1 2000-01-02 1 20 1.5 25 1.5 25
2 2000-01-09 2 30 1.5 25 1.5 25
3 2000-01-16 3 40 1.5 25 1.5 25
您也可以使用 pandas.concat
代替 DataFrame.join
:
methods = ['mean', 'median', 'std', 'min', 'max']
pd.concat([
df, *[g.transform(m).add_suffix(f'_{m}') for m in methods]
], axis='columns')
这给你:
Publish date ID Price ID_mean Price_mean ID_median Price_median ID_std Price_std ID_min Price_min ID_max Price_max
0 2000-01-02 0 10 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
1 2000-01-02 1 20 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
2 2000-01-09 2 30 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40
3 2000-01-16 3 40 1.5 25 1.5 25 1.290994 12.909944 0 10 3 40