我有一个如下的数据集(样本)
Date Value
2019-05-01 0
2019-05-02 0
2019-05-03 0
2019-05-04 0
2019-05-05 0
2019-05-06 0
2019-05-07 0
2019-05-08 1
2019-05-09 0
我想对其进行转换,以便在遇到Value = 1时,将2天前的3个值取为1。并将当前值设置为0。 换句话说,转换后的数据集应该看起来像这样
Date Value
2019-05-01 0
2019-05-02 0
2019-05-03 1
2019-05-04 1
2019-05-05 1
2019-05-06 0
2019-05-07 0
2019-05-08 0
2019-05-09 0
请注意,在上面的示例中,转换后将2019-05-08设置为0,并将2019-05-03至2019-05-05设置为1(最后设置为1的值是在转换前2天2019-05-08和2019-05-05之前的3天也设置为1)。 如果两个连续的值显示为1,我们将从显示为1的最后一个值开始日期计算。 我想我可以通过for循环来做到这一点,但一直在寻找是否有任何内置函数可以帮助我解决这个问题。 谢谢!
答案 0 :(得分:1)
可能有更精确的方法来解决此问题。但是,我只能考虑使用索引值(例如i),其中Value==1
来解决此问题,然后在之前的位置获取索引值(前2个日期表示i-3,然后在其上方的两个值表示i- 4,i-5),并将Value
分配给1。最后,将Value
最初找到的索引位置的Value==1
设置回0。
In [53]: df = pd.DataFrame({'Date':['2019-05-01','2019-05-02', '2019-05-03','2019-05-04','2019-05-05', '2019-05-06','20
...: 19-05-07','2019-05-08','2019-05-09'], 'Value':[0,0,0,0,0,0,0,1,0]})
...:
...:
In [54]: val_1_index = df.loc[df.Value == 1].index.tolist()
In [55]: val_1_index_decr = [(i-3, i-4, i-5) for i in val_1_index]
In [56]: df.loc[df['Value'].index.isin([i for i in val_1_index_decr[0]]), 'Value'] = 1
In [57]: df.loc[df['Value'].index.isin(val_1_index), 'Value'] = 0
In [58]: df
Out[58]:
Date Value
0 2019-05-01 0
1 2019-05-02 0
2 2019-05-03 1
3 2019-05-04 1
4 2019-05-05 1
5 2019-05-06 0
6 2019-05-07 0
7 2019-05-08 0
8 2019-05-09 0
答案 1 :(得分:1)
一种解决方案,假设df
是您的原始数据帧:
df['Value'] = pd.Series([1 if 1 in df.iloc[i+3:i+6].values else 0 for i in df.index])
在这里,我处理索引而不是日期,所以我假设您每行有一天,并且天是连续的,如示例所示。
也适合此请求:
如果两个连续的值显示为1,我们将从显示为1的最后一个值开始日期计算。
我可以提出两行解决方案:
validones = [True if df.iloc[i]['Value'] == 1 and df.iloc[i+1]['Value'] == 0 else False for i in df.index]
df['Value'] = pd.Series([1 if any(validones[i+3:i+6]) else 0 for i in range(len(validones))])
基本上,我首先建立一个布尔值列表,以检查df['Value']
中的1是否后面没有另一个1,然后使用该布尔值列表进行替换。
答案 2 :(得分:0)
不确定该解决方案的效率,因为一个人需要创建三个新列,但这也行得通:
df['shiftedValues'] = \
df['Value'].shift(-3, fill_value=0) + \
df['Value'].shift(-4, fill_value=0) + \
df['Value'].shift(-5, fill_value=0)
请注意,转换是按行而不是按天完成的。
要按实际天数移动,我首先要按日期编制索引
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index('Date')
df['shiftedValues'] = \
df['Value'].shift(-3, freq='1D', fill_value=0).asof(df.index) + \
df['Value'].shift(-4, freq='1D', fill_value=0).asof(df.index) + \
df['Value'].shift(-5, freq='1D', fill_value=0).asof(df.index)
# Out:
# Value shiftedValues
# Date
# 2019-05-01 0 0.0
# 2019-05-02 0 0.0
# 2019-05-03 0 1.0
# 2019-05-04 0 1.0
# 2019-05-05 0 1.0
# 2019-05-06 0 0.0
# 2019-05-07 0 0.0
# 2019-05-08 1 0.0
# 2019-05-09 0 0.0
现在,这对于日期是正确的,例如,如果df是(请注意缺少和重复的日期)
Date Value
0 2019-05-01 0
1 2019-05-02 0
2 2019-05-03 0
3 2019-05-04 0
4 2019-05-05 0
5 2019-05-05 0
6 2019-05-07 0
7 2019-05-08 1
8 2019-05-09 0
那么你就得到
Value shiftedValues
Date
2019-05-01 0 0.0
2019-05-02 0 0.0
2019-05-03 0 1.0
2019-05-04 0 1.0
2019-05-05 0 1.0
2019-05-05 0 1.0
2019-05-07 0 0.0
2019-05-08 1 0.0
2019-05-09 0 0.0