########## Recreating OP's DF ##############
Name = ["John", "John", "Mary", "Steve", "Mary", "John", "John", "Mary", "John"]
Date = ["2022-01-01", "2022-01-01", "2022-01-01", "2022-01-03", "2022-01-03",
"2022-01-02", "2022-01-03", "2022-01-04", "2022-01-04"]
df = pd.DataFrame({"Name":Name, "Date":Date})
df.Date = pd.to_datetime(df.Date)
############################################
# Sort the dataframe first by name then by date
df = df.sort_values(by=["Name", "Date"]).reset_index(drop=True)
# Loop through all of the unique names and create a sub-dataframe for them
allCount = [] # empty count list
for name in df.Name.unique():
nameDF = df[df.Name == name].reset_index(drop=True)
# Check if the next day is 1 day after the previous day (consecutive)
# If it is, add to the count value
count = 1
for y in range(len(nameDF)-1):
if nameDF.Date[y+1] == nameDF.Date[y] + pd.Timedelta(days=1):
count += 1
allCount.append(count) # append all count values for all names
# Make a new DF with the consecutive day count
consecutiveDF = pd.DataFrame({"Name":df.Name.unique(), "consecutive_days":allCount})
# Drop any row that does not have at least 1 consecutive day
consecutiveDF = consecutiveDF[consecutiveDF.consecutive_days > 1].reset_index(drop=True)
consecutiveDF
Output:
Name consecutive_days
0 John 4
1 Mary 2
Maybe some list comprehension instead of a nest for loop can speed it up:
# Sort the dataframe first by name then by date
df = df.sort_values(by=["Name", "Date"]).reset_index(drop=True)
# Loop through all of the unique names and create a sub-dataframe for them
allCount = [] # empty count list
for name in df.Name.unique():
nameDF = df[df.Name == name].reset_index(drop=True)
# Check if the next day is 1 day after the previous day (consecutive)
# If it is, add to the count value
days = ["day" for y in range(len(nameDF)-1) if nameDF.Date[y+1] == nameDF.Date[y] + pd.Timedelta(days=1)]
allCount.append(len(days)+1)
# Make a new DF with the consecutive day count
consecutiveDF = pd.DataFrame({"Name":df.Name.unique(), "consecutive_days":allCount})
# Drop any row that does not have at least 1 consecutive day
consecutiveDF = consecutiveDF[consecutiveDF.consecutive_days > 1].reset_index(drop=True)
consecutiveDF