I have a dataframe that looks like this
df = pd.DataFrame({'Col1':[0,1,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0]})
I want to have a rolling function where if the value of 1 appears, the next 5 rows will flip to 0.
I think it'll be have to an iterative process, but not sure how best to implement it.
This is the desired df using the above rule.
df_desired = pd.DataFrame({'Col1':[0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0]})
Thanks
F
CodePudding user response:
So to do this, you'll want to find all the indices of df that are equal to 1 and then find all the indices that are greater than 5 apart from each other consecutively.
df = pd.DataFrame({'Col1':[0,1,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0]})
ind = df[df['Col1'] == 1].index #get the indices where df == 1
#find all the indices that are consecutively greater than 5 apart
val = [ind[0]]
for k in ind[1:]:
if k - val[-1] > 5:
val.append(k)
df['Col1'] = 0 #change all the values to zero
df['Col1'][val] = 1 #change all indices where there was spaced ones to 1
CodePudding user response:
Here is a simple solution:
i = 0
while i < (len(list) - 5):
if list[i] == 1:
list[i 1:i 6] = [0]*5
i = 6
i = 1
print(list)
You just replace the slice of the next 5 values with 0's. ([0]*5 creates such an array). Then you skip by 6 if you replaced, otherwise just by the usual 1.
Of course you need to convert to a list first using pd.Series.tolist(). Then you can add it back
CodePudding user response:
Another solution to what has already been provided. This just iterates through the data frame. Each time it encounters a 1, it will start flipping the next 5 elements to 0.
import pandas as pd
no_of_flips = 5
df = pd.DataFrame({'Col1':[0,1,0,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,0,0]})
df_desired = pd.DataFrame({'Col1':[0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0]})
for inx in df.index:
if i > 0:
df.at[inx, 'Col1'] = 0
i -= 1
if df.loc[inx,'Col1'] == 1:
i = no_of_flips
if (df.compare(df_desired)).empty:
print('Both dataFrames are the same!')
else:
print('Dataframes are different')