Survey and CRM exports often cram several values into one cell: "Python, SQL , python".
df has an id column and a tags column of comma-separated strings (which may be empty or NaN). Implement:
tag_counts(df): a pd.Series mapping each tag to the number of rows containing it. Tags are stripped and lowercased, empty tags are dropped, and a tag repeated within one row counts once. Sort by count descending, then tag alphabetically.cooccurrence(df): a dict mapping (a, b) with a < b to the number of rows containing both tags