提问人:Question1010 提问时间:10/31/2023 更新时间:10/31/2023 访问量:53
重新采样('W')奇怪的结果
Resample('W') weird results
问:
我有一个包含每日日期的 pandas DataFrame,在这个 DataFrame 中,缺少一些日期。我的目标是从该 DataFrame 生成一个新的时间序列,该时间序列仅包含每周的最后一天。例如,如果特定周只有星期三和星期四条目,则生成的时间序列应仅保留该周的星期四数据点。
例如,我尝试了以下操作:
import pandas as pd
import numpy as np
# Create a sample time series with date index
#SUNDAY, MONDAY, TUESDAY, WED, THURSDAY
date_list = ['2023-10-01', '2023-10-02', '2023-10-03', '2023-10-04', '2023-10-05']
# Convert the date list to a pandas datetime index
date_rng = pd.to_datetime(date_list)
data = np.random.rand(len(date_rng))
time_series = pd.Series(data, index=date_rng)
# Resample the time series to weekly frequency and select the last observation for each week
weekly_last = time_series.resample('W').last()
weekly_last['Day of the Week'] = weekly_last.index.day_name()
# Print the result
print(weekly_last)
打印: ['SUNDAY', 'SUNDAY'] 而它应该打印 ['SUNDAY', 'THURSDAY']
所以我真的不知道如何实现我想要的?非常感谢您的帮助
答:
2赞
Michael Cao
10/31/2023
#1
我选择通过计算天数整数除以 7 的差值来计算周 #。我还选择减去哪个日期,以防您不想要周日至周六的一周。我还更改了初始日期范围以更好地证明这一点。
# Create a sample time series with date index
#SUNDAY, MONDAY, TUESDAY, WED, THURSDAY
# date_list = ['2023-10-01', '2023-10-02', '2023-10-03', '2023-10-04', '2023-10-05']
date_list = np.arange(np.datetime64('2023-10-01'), np.datetime64('2023-10-31'), np.timedelta64(3, 'D'))
df = pd.DataFrame(date_list)
offset_day = df.loc[0, 0]
df['Day of Week'] = df[0].dt.day_name()
df['Week #'] = (df[0] - offset_day).dt.days // 7
print(df)
print(df.groupby('Week #').last())
评论
0赞
Question1010
10/31/2023
你确定它有效吗?结果应为 ['Sunday', 'Saturday', 'Friday', 'Sunday', 'Saturday'],而不是:[Saturday, Friday, Thursday, Saturday]
0赞
Michael Cao
10/31/2023
这完全取决于你对一周的开始和结束的定义。这就是为什么我给你一个选项来设置 .目前,我只使用表格中的第一天,即星期日,所以我的周被定义为从星期日到星期六。看起来您想要一个周一到周日的一周,您可以通过设置 .offset_day
offset_day = np.datetime64('09-25-23')
1赞
Tom
10/31/2023
#2
您可以使用 isocalendar()
方法来获取一年中的一周,然后对其进行分组:
df = pd.DataFrame({'date': date_rng, 'value': data})
df['week'] = df['date'].dt.isocalendar().week
grouped = df.groupby('week').last().set_index('date')
weekly_last = grouped['value'].copy()
然后你得到预期的结果:
>>> weekly_last.index.day_name()
Index(['Sunday', 'Thursday'], dtype='object', name='date')
使用 重新采样时,您可以根据需要每周对数据进行分组。但是,索引上分配的标签将是相应的星期日。你可以选择一个不同的日间锚点,但这对你没有帮助。因此,您基本上需要通过保留原始日期作为标签来进行相同的分组。'W'
为此,您可以对一年中编号的周进行分组,每周进行最后一次观测,并将该日期用于索引。除了对 resample/groupby 的调用之外,这需要一些额外的步骤,因为。
几点说明:
- 如果直接按一年中的星期 ( 进行分组,则会丢失日期,并且只会在索引中看到一年中的星期。这就是为什么我在数据帧中收集东西的原因 - 然后日期保留在它们自己的列中,你可以用它来使它们成为索引。
time_series.groupby(time_series.index.isocalendar().week).last()
set_index()
- 目前,您还可以使用
weekofyear
属性来获取一年中的周。但是我在使用它时收到弃用警告,以及使用 .isocalendar()
1赞
Corralien
10/31/2023
#3
若要获取预期输出,请重置日期时间索引以保留它:
weekly_last = (time_series.to_frame('value').reset_index(names='ts')
.groupby(pd.Grouper(freq='W', key='ts'))
.agg({'ts': 'last', 'value': 'last'})
.set_index('ts')['value'].rename_axis(None).rename(None))
输出:
>>> weekly_last
2023-10-01 0.063242
2023-10-05 0.400444
dtype: float64
>>> weekly_last.index.day_name()
Index(['Sunday', 'Thursday'], dtype='object')
评论
0赞
Question1010
10/31/2023
谢谢!它工作得很好。在效率方面,使用带有 isocalendar 函数的 groupby 或您的代码的解决方案更好吗?
0赞
Corralien
10/31/2023
两种解决方案都使用...但是,您可以替换为 。我不知道哪种解决方案更好,我只是从您的数据开始,所以我必须转换为数据帧并重置索引。groupby
.groupby(pd.Grouper(freq='W', key='ts'))
.resample('W', on='ts')
评论