将 pandas 数据框中的一些行添加到下一个,然后删除它们

Add some rows from pandas dataframe to next, then remove them

我有一个包含很多列的 pandas 数据框,其中一些在周末有值。

我现在正尝试删除所有周末行,但需要将我删除的值添加到相应的下周一。

Thu: 4
Fri: 5
Sat: 2
Sun: 1
Mon: 4
Tue: 3

需要成为

Thu: 4
Fri: 5
Mon: 7
Tue: 3

我已经想出了如何只对工作日进行切片(使用 df.index.dayofweek),但在这样做之前想不出一个巧妙的聚合方法。

下面是一些虚拟代码:

index = pd.date_range(datetime.datetime.now().date() -
                      datetime.timedelta(20),
                      periods = 20,
                      freq = 'D')

df = pd.DataFrame({
    'Val_1': np.random.rand(20),
    'Val_2': np.random.rand(20),
    'Val_3': np.random.rand(20)
  },
  index = index)

df['Weekday'] = df.index.dayofweek

如有任何帮助,我们将不胜感激!

设置

我添加了一个随机种子

np.random.seed([3, 1415])

index = pd.date_range(datetime.datetime.now().date() -
                      datetime.timedelta(20),
                      periods = 20,
                      freq = 'D')

df = pd.DataFrame({
    'Val_1': np.random.rand(20),
    'Val_2': np.random.rand(20),
    'Val_3': np.random.rand(20)
  },
  index = index)

df['day_name'] = df.index.day_name()

df.head(6)

               Val_1     Val_2     Val_3   day_name
2018-07-18  0.444939  0.278735  0.651676  Wednesday
2018-07-19  0.407554  0.609862  0.136097   Thursday
2018-07-20  0.460148  0.085823  0.544838     Friday
2018-07-21  0.465239  0.836997  0.035073   Saturday
2018-07-22  0.462691  0.739635  0.275079     Sunday
2018-07-23  0.016545  0.866059  0.706685     Monday

解决方案

星期六和星期天我填了一系列日期后面的星期一。在操作组中使用。

weekdays = df.index.to_series().mask(df.index.dayofweek >= 5).bfill()

d_ = df.groupby(weekdays).sum()
d_

               Val_1     Val_2     Val_3
2018-07-18  0.444939  0.278735  0.651676
2018-07-19  0.407554  0.609862  0.136097
2018-07-20  0.460148  0.085823  0.544838
2018-07-23  0.944475  2.442691  1.016837
2018-07-24  0.850445  0.691271  0.713614
2018-07-25  0.817744  0.377185  0.776050
2018-07-26  0.777962  0.225146  0.542329
2018-07-27  0.757983  0.435280  0.836541
2018-07-30  2.645824  2.198333  1.375860
2018-07-31  0.926879  0.018688  0.746060
2018-08-01  0.721535  0.700566  0.373741
2018-08-02  0.117642  0.900749  0.603536
2018-08-03  0.145906  0.764869  0.775801
2018-08-06  0.738110  1.580137  1.266593

比较

df.join(d_, rsuffix='_')

               Val_1     Val_2     Val_3   day_name    Val_1_    Val_2_    Val_3_
2018-07-18  0.444939  0.278735  0.651676  Wednesday  0.444939  0.278735  0.651676
2018-07-19  0.407554  0.609862  0.136097   Thursday  0.407554  0.609862  0.136097
2018-07-20  0.460148  0.085823  0.544838     Friday  0.460148  0.085823  0.544838
2018-07-21  0.465239  0.836997  0.035073   Saturday       NaN       NaN       NaN
2018-07-22  0.462691  0.739635  0.275079     Sunday       NaN       NaN       NaN
2018-07-23  0.016545  0.866059  0.706685     Monday  0.944475  2.442691  1.016837
2018-07-24  0.850445  0.691271  0.713614    Tuesday  0.850445  0.691271  0.713614
2018-07-25  0.817744  0.377185  0.776050  Wednesday  0.817744  0.377185  0.776050
2018-07-26  0.777962  0.225146  0.542329   Thursday  0.777962  0.225146  0.542329
2018-07-27  0.757983  0.435280  0.836541     Friday  0.757983  0.435280  0.836541
2018-07-28  0.934829  0.700900  0.538186   Saturday       NaN       NaN       NaN
2018-07-29  0.831104  0.700946  0.185523     Sunday       NaN       NaN       NaN
2018-07-30  0.879891  0.796487  0.652151     Monday  2.645824  2.198333  1.375860
2018-07-31  0.926879  0.018688  0.746060    Tuesday  0.926879  0.018688  0.746060
2018-08-01  0.721535  0.700566  0.373741  Wednesday  0.721535  0.700566  0.373741
2018-08-02  0.117642  0.900749  0.603536   Thursday  0.117642  0.900749  0.603536
2018-08-03  0.145906  0.764869  0.775801     Friday  0.145906  0.764869  0.775801
2018-08-04  0.199844  0.253200  0.091238   Saturday       NaN       NaN       NaN
2018-08-05  0.437564  0.548054  0.504035     Sunday       NaN       NaN       NaN
2018-08-06  0.100702  0.778883  0.671320     Monday  0.738110  1.580137  1.266593

使用简单系列设置数据,使周末滚动值显而易见:

index = pd.date_range(start='2018-07-18', periods = 20, freq = 'D')

df = pd.DataFrame({
    'Val_1': [1] * 20,
    'Val_2': [2] * 20,
    'Val_3': [3] * 20,
  },
  index = index)

您可以计算数据框中相关列的累计总和,然后使用工作日布尔过滤器对结果进行差分。您需要应用一些特殊的逻辑来根据第一天是工作日、周六还是周日来正确计算第一天。

使用 7 月 21 日(星期六)和 22 日(星期日)的指数开始日期可以观察到正确的滚动行为。

此外,您可能需要考虑最后一两天是周末的情况。照原样,这些值将丢失。根据情况,您可能希望将它们向前滚动到下一个星期一(在这种情况下您需要扩展索引)或者将它们回滚到前一个星期五。

weekdays = df.index.dayofweek < 5

df2 = df.iloc[:, :].cumsum()[weekdays].diff()
if weekdays[0]:
    # First day is a weekday, so just use its value.
    df2.iloc[0, :] = df.iloc[0, :]
elif weekdays[1]:
    # First day must be a Sunday.
    df2.iloc[0, :] = df.iloc[0:2, :].sum()
else:
    # First day must be a Saturday.
    df2.iloc[0, :] = df.iloc[0:3, :].sum()

>>> df2.head(14)
            Val_1  Val_2  Val_3
2018-07-18      1      2      3
2018-07-19      1      2      3
2018-07-20      1      2      3
2018-07-23      3      6      9
2018-07-24      1      2      3
2018-07-25      1      2      3
2018-07-26      1      2      3
2018-07-27      1      2      3
2018-07-30      3      6      9
2018-07-31      1      2      3
2018-08-01      1      2      3
2018-08-02      1      2      3
2018-08-03      1      2      3
2018-08-06      3      6      9