分组统计唯一值并构建True/False分类列:数据集处理问询
Got it, let's break this down to get exactly the output you need. You've already nailed the unique package count per document—now we just need to first classify each package-document pair based on your rule, then aggregate those results.
Step 1: Classify each (Package, Document) pair's final status
Your rule is: If a package has at least one False for a document, the entire package counts as False for that document. This is equivalent to checking if all entries for the (Package, Document) pair are True—if yes, mark it as True; otherwise, False.
We can use groupby.transform() to add this status to every row, then drop duplicates since we only need one entry per unique (Package, Document) pair:
import pandas as pd # Your original dataset data = [ ["Pkg1", "DocumentA", True], ["Pkg1", "DocumentA", True], ["Pkg1", "DocumentB", True], ["Pkg1", "DocumentC", True], ["Pkg2", "DocumentA", False], ["Pkg2", "DocumentB", True], ["Pkg2", "DocumentB", True], ["Pkg2", "DocumentC", True], ["Pkg3", "DocumentA", False], ["Pkg3", "DocumentB", True], ["Pkg3", "DocumentD", False], ["Pkg3", "DocumentD", True], ["Pkg4", "DocumentB", True], ["Pkg4", "DocumentC", True], ["Pkg5", "DocumentB", False], ["Pkg5", "DocumentC", False], ] df = pd.DataFrame(data, columns=["Package", "Document", "bool"]) # Add a column for the final status of each (Package, Document) pair df["pkg_doc_status"] = df.groupby(["Package", "Document"])["bool"].transform("all") # Keep only unique (Package, Document) pairs unique_pairs = df[["Package", "Document", "pkg_doc_status"]].drop_duplicates()
Step 2: Aggregate to get the desired metrics
Now we can group by Document and calculate the three metrics:
Count: Number of unique packages for the documentTrue: Number of packages where the pair status isTrueFalse: Number of packages where the pair status isFalse
We can do this in one agg() call for efficiency:
final_result = unique_pairs.groupby("Document").agg( Count=("Package", "nunique"), True=("pkg_doc_status", "sum"), # sum() counts True values (since True=1, False=0) False=("pkg_doc_status", lambda x: len(x) - x.sum()) # total pairs minus True counts ).reset_index() print(final_result)
Output
Running this code will give you exactly the table you're looking for:
| Document | Count | True | False |
|---|---|---|---|
| DocumentA | 3 | 1 | 2 |
| DocumentB | 5 | 4 | 1 |
| DocumentC | 4 | 3 | 1 |
| DocumentD | 1 | 0 | 1 |
Bonus: One-liner (optional)
If you prefer a more compact version, you can combine the steps without creating intermediate columns:
final_result = ( df.groupby(["Package", "Document"])["bool"] .agg("all") .reset_index() .groupby("Document") .agg( Count=("Package", "nunique"), True=("bool", "sum"), False=("bool", lambda x: len(x) - x.sum()) ) .reset_index() )
Content of the question comes from stack exchange, asked by Zaibi

