Pandas -按周列计算列的总和

iecba09b  于 2023-01-19  发布在  其他
关注(0)|答案(3)|浏览(146)

我有一个如下所示的表,其中包含多个ID的值:
| 识别号|价值|日期|
| - ------|- ------|- ------|
| 1个|二十个|2022年1月1日12时20分|
| 第二章|二十五|2022年1月4日18时20分|
| 1个|十个|2022年1月4日11时20分|
| 1个|一百五十|2022年1月6日16时20分|
| 第二章|二百|2022年1月8日13时20分|
| 三个|四十|2022年1月4日21时20分|
| 1个|七十五|2022年1月9日08时20分|
我想计算所有ID的每周值总和:

  • 开始日期已给定(例如,01-01-2022)。
  • 周数基于以下范围计算:
  • 每周六00:00至下周五23:59(即第1周为2022年1月1日00:00至2022年1月7日23:59)

| 识别号|第1周总和|第2周总和|第3周总和|...|
| - ------|- ------|- ------|- ------|- ------|
| 1个|一百八十|七十五|--|--|
| 第二章|二十五|二百|--|--|
| 三个|四十|--|--|--|

rxztt3cl

rxztt3cl1#

有一个panda函数(pd.Grouper)允许您指定groupby指令。1在本例中,该指定是按照从星期五开始的每周频率对日期进行“重新采样”。2由于您还需要按照ID进行分组,因此将其添加到grouper中。

# convert to datetime
df['date'] = pd.to_datetime(df['date'])
# pivot the dataframe
df1 = (
    df.groupby(['ID', pd.Grouper(key='date', freq='W-FRI')])['value'].sum()
    .unstack(fill_value=0)
)
# rename columns
df1.columns = [f"Week {c} sum" for c in range(1, df1.shape[1]+1)]
df1 = df1.reset_index()

1您实际需要的是pivot_table结果,但groupby + unstack is equivalent to pivot_tablegroupby + unstack在这里更方便。
2由于2022年1月1日是星期六,您需要指定星期五的锚。

w1e3prcc

w1e3prcc2#

您可以计算周列。如果您有同一年的数据,您可以只提取周数,这在实时场景中不太可能。如果您有多个年份的数据,导出年和周数的组合可能是明智的。

df['Year-Week'] = df['Date'].dt.strftime('%Y-%U')

在您的情况下,日期2022-01-01 & 2022-01-04 18:2应根据您考虑的方案转换为2022-01。
要计算透视表,可以使用panda pivot_table。示例代码:

pd.pivot_table(df, values='value', index=['ID'], columns=['year_weeknumber'], aggfunc=np.sum)
klr1opcd

klr1opcd3#

让我们定义一个格式化助手。

def fmt(row):
    return f"{row.year}-{row.week:02d}"  # We ignore row.day

现在很简单了。

>>> df = pd.DataFrame([dict(id=1, value=20, date="2022-01-01 12:20"),
                       dict(id=2, value=25, date="2022-01-04 18:20")])
>>> df['date'] = pd.to_datetime(df.date)
>>> df['iso'] = df.date.dt.isocalendar().apply(fmt, axis='columns')
>>> df
   id  value                date      iso
0   1     20 2022-01-01 12:20:00  2021-52
1   2     25 2022-01-04 18:20:00  2022-01

按ISO周分组。

相关问题