将 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
我有一个包含很多列的 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