我有一个看起来像这样的数据框:
Name Date
Person A 2019-06-18
Person A 2019-05-14
Person A 2019-04-03
Person B 2019-05-19
Person C 2019-05-16
Person C 2019-05-23
Person C 2019-05-15
Person D 2019-06-21
我想做的是修改5/14到6/14之间任何人的日期,并减去7天。如果完成此操作后,它们仍然在该范围内,请再减去7天。
最后,我希望数据看起来像这样:
Name Date
Person A 2019-06-18
Person A 2019-05-07
Person A 2019-04-03
Person B 2019-05-12
Person C 2019-05-09
Person C 2019-05-09
Person C 2019-05-08
Person D 2019-06-21
(此步骤之后,我将其汇总起来,以便每个人都将其所有日期排成一行,然后向他们发送其信息-但我想我可以自己弄清楚这一点。)
现在,我有以下代码“正在运行”:
df = df[(df['Date'] >= '2019-05-14') & (df['Date'] <= '2019-06-14')]
df['Date'] = df['Date'] - pd.Timedelta(days=7)
但是,我不知道如何循环它,我也不知道如何应用它而不丢失原始数据。
因此,我的代码生成了以下框架:
Name Date
Person A 2019-05-07
Person B 2019-05-12
Person C 2019-05-16
Person C 2019-05-08
答案 0 :(得分:3)
我只计算一下每个日期要减去多少次,并一步一步完成
m = df.Date.between('2019-05-14', '2019-06-14')
u = df[m]
d = u.Date - pd.Timestamp('2019-05-13')
o = np.ceil(d.dt.days / 7)
df.loc[m, 'Date'] = df.loc[m, 'Date'] - (o * np.timedelta64(7, 'D'))
Name Date
0 Person A 2019-06-18
1 Person A 2019-05-07
2 Person A 2019-04-03
3 Person B 2019-05-12
4 Person C 2019-05-09
5 Person C 2019-05-09
6 Person C 2019-05-08
7 Person D 2019-06-21
这是一个不会就地修改框架的版本:
m = df.Date.between('2019-05-14', '2019-06-14')
d = df.Date - pd.Timestamp('2019-05-13')
o = np.ceil(d.dt.days / 7)
df.assign(Date=np.where(m, df.Date - (o * np.timedelta64(7, 'D')), df.Date))
Name Date
0 Person A 2019-06-18
1 Person A 2019-05-07
2 Person A 2019-04-03
3 Person B 2019-05-12
4 Person C 2019-05-09
5 Person C 2019-05-09
6 Person C 2019-05-08
7 Person D 2019-06-21
答案 1 :(得分:1)
我们可以使用range()
进行简单循环,然后使用numpy.where
有条件地更改每行(如果两个日期之间):
for i in range(2):
df['Date'] = np.where(df['Date'].between('20190514','20190614'),
df['Date'] - pd.Timedelta(days=7),
df['Date'])
print(df)
Name Date
0 Person A 2019-06-18
1 Person A 2019-05-07
2 Person A 2019-04-03
3 Person B 2019-05-12
4 Person C 2019-05-09
5 Person C 2019-05-09
6 Person C 2019-05-08
7 Person D 2019-06-21
答案 2 :(得分:1)
您可以通过编写一个函数,然后将其应用于日期列来执行此操作。 pd.Series.apply
方法通过将每个值传递给提供的函数来工作。在该函数中,您有一个简单的while循环,该循环将持续减少7天,直到您位于所需的日期范围内。
from datetime import datetime as dt
from datetime import timedelta
def date_modifier(x):
d = x
while True:
if d >= dt(2019, 5, 14) and d<=dt(2019, 6, 14):
d-= timedelta(days=7)
else:
return d
df['Date-Mod'] = df['Date'].apply(date_modifier)
给出以下输出:
Name Date Date-Mod
0 PersonA 2019-06-18 2019-06-18
1 PersonA 2019-05-14 2019-05-07
2 PersonA 2019-04-03 2019-04-03
3 PersonB 2019-05-19 2019-05-12
4 PersonC 2019-05-16 2019-05-09
5 PersonC 2019-05-23 2019-05-09
6 PersonC 2019-05-15 2019-05-08
7 PersonD 2019-06-21 2019-06-21
答案 3 :(得分:1)
我假设Date
列是datetime64
类型。
第一步是定义“边界日期”:
start_date = pd.to_datetime('2019-05-14')
end_date = pd.to_datetime('2019-06-14')
然后,我们必须定义要应用于每个日期的函数:
def fn(dat):
inRng = (dat >= start_date) & (dat <= end_date)
dat2 = dat
if inRng:
diffWeeks = int((dat - start_date) / np.timedelta64(1, 'W')) + 1
dat2 -= np.timedelta64(diffWeeks, 'W')
return dat2
最后一步是应用此功能。
为了简化源数据和结果的比较,我决定替代
结果显示在新列(Dat2
)中:
df['Dat2'] = df.Date.apply(fn)
打印DataFrame时,您将获得:
Name Date Dat2
0 Person A 2019-06-18 2019-06-18
1 Person A 2019-05-14 2019-05-07
2 Person A 2019-04-03 2019-04-03
3 Person B 2019-05-19 2019-05-12
4 Person C 2019-05-16 2019-05-09
5 Person C 2019-05-23 2019-05-09
6 Person C 2019-05-15 2019-05-08
7 Person D 2019-06-21 2019-06-21