Deduplicate clicked search IDs and attach markers to searches before weekly grouping. Use searched_at, not clicked_at, to assign the week. Any matching click in the provided clicks table marks its search as clicked, even if the click occurs in a later week.
index
time
clicked
0
2026-07-06T08:00:00Z
1
1
2026-07-12T23:00:00Z
0
2
2026-07-13T00:00:00Z
1
↓
index
week_start
searches
clicked_searches
0
2026-07-06 00:00:00+00:00
2
1
1
2026-07-13 00:00:00+00:00
1
1
Assign each search to its search-time week, with its click marker already attached.
Retain the complete weekly calendar
Report the eight Monday-start UTC weeks beginning July 6 through August 24, 2026. Keep weeks with no searches as zero counts. Their CTR is missing because the denominator is zero; the first absolute search change is missing because no earlier report week is available.
index
searches
clicked_searches
0
4
2
1
0
0
2
6
3
↓
index
searches
clicked_searches
search_ctr
search_change
0
4
2
0.5
NA
1
0
0
NA
-4
2
6
3
0.5
6
A zero-search week has no defined CTR, but its absolute volume change is valid.
Export the report with explicit labels
Use .to_csv(index=False, date_format="%Y-%m-%d") for a CSV string with UTC week-start dates such as 2026-07-06. This omits the row index and leaves missing numeric cells empty. Keep the full precision of rates; the CSV date labels refer to UTC Mondays.
▷ Your turn
For the eight Monday-start UTC weeks from July 6 through August 30, 2026, return week_start, searches, clicked_searches, and search_ctr. Label weeks July 6 through August 24, ascending. Count each searched_at event in its own week; a matching click anywhere in the supplied clicks table marks that search once. Keep zero-count weeks with missing CTR. Exclude missing timestamps and searches outside [July 6, August 31). Keep UTC timestamps and unrounded rates. Save the DataFrame as result.