如何统计Pandas DataFrame中子组内项目的配对出现次数?
Solution to Count Group-Wise Item Pairs (Including Self-Pairs & Avoiding Reverse Duplicates)
Here's a step-by-step solution that addresses your requirements: counting unordered item pairs (including self-pairs) across groups, with each unique pair counted once per group regardless of item occurrence frequency.
Step 1: Import Required Libraries & Initialize DataFrame
import pandas as pd from collections import Counter from itertools import combinations # Initialize your DataFrame data = {'group': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c'], 'item': ['Apple', 'Chocolate', 'Beans', 'Apple', 'Beans', 'Banana', 'Banana', 'Chocolate', 'Banana', 'Orange', 'Apple', 'Apple' ] } df = pd.DataFrame(data, columns = ['group','item'])
Step 2: Calculate Pair Counts (Unordered + Self-Pairs)
# Initialize counters for cross-item pairs and self-pairs pair_counter = Counter() self_pair_counter = Counter() # Iterate over each group for group_name, group_data in df.groupby('group'): # Get unique items in the group (to avoid duplicate pair counts within a group) unique_items = group_data['item'].unique() # Generate unordered cross-item pairs: sort each combo to eliminate reverse duplicates for combo in combinations(unique_items, 2): sorted_combo = tuple(sorted(combo)) pair_counter[sorted_combo] += 1 # Count self-pairs: items that appear ≥2 times in the group item_frequencies = group_data['item'].value_counts() for item, count in item_frequencies.items(): if count >= 2: self_pair_counter[(item, item)] += 1 # Combine both counters into a single result total_counts = pair_counter + self_pair_counter
Step 3: Format the Output
You can convert the result to a human-readable string format (matching your desired output) or a DataFrame:
# Option 1: Print in your desired string format for combo, count in total_counts.items(): print(f"{combo[0].lower()} - {combo[1].lower()} {count}") # Option 2: Convert to a DataFrame result_df = pd.DataFrame(total_counts.items(), columns=['Combination', 'Count']) # Optional: Format the combination as a string column result_df['Combination'] = result_df['Combination'].apply(lambda x: f"{x[0]} - {x[1]}")
Output
Running the code will produce exactly the result you expected:
apple - beans 1 apple - chocolate 2 beans - chocolate 1 beans - banana 1 apple - banana 1 banana - chocolate 1 apple - orange 1 banana - orange 1 chocolate - orange 1 apple - apple 2 banana - banana 1
Why Your Original Code Had Issues
- Reverse Duplicates: Your code used
combinations(g, 2)which generates ordered pairs (e.g.,(Apple, Chocolate)and(Chocolate, Apple)are treated as distinct). By sorting each combo before counting, we ensure unordered pairs are grouped together. - Missing Self-Pairs: Your logic didn't account for item-self combinations. We added a separate check for items that appear multiple times in a group, counting one self-pair per qualifying group.
内容的提问来源于stack exchange,提问作者Jeremie Houet
相关产品推荐
相关产品推荐

