Find grains and mappings
Does each exam belong to one site? Use df and fw from Getting started to check whether repeated records for an exam agree about its site.
Look for a mapping
Section titled “Look for a mapping”dependencies = fw.discover_dependencies( df, features=["exam", "site"], max_key_size=1,)candidates = dependencies.to_frame("candidates")print( candidates[ ["columns", "groups", "repeated_groups", "determines"] ].to_string(index=False))columns groups repeated_groups determines [exam] 3 3 [site] [site] 2 2 []A candidate is a column, or combination of columns, that might identify a useful group. Here each exam occurs twice. A unique row identifier would also determine the other fields, but it would tell us nothing about agreement across repeated records.
Read the findings to see which mappings hold:
findings = dependencies.to_frame("findings")print(findings[["id", "statement"]].to_string(index=False))id statementf0 exam determines siteExam determines site: every row for exam 1 says North, as does every row for exam 2, while exam 3 belongs to South. Site does not determine exam because North contains two exams.
Check the support behind the mapping
Section titled “Check the support behind the mapping”Read the target-specific evidence, especially when attributes are missing:
support = dependencies.to_frame("dependencies")print( support[ ["determinant", "target", "target_coverage", "repeat_coverage", "repeat_modal_accuracy"] ].to_string(index=False))determinant target target_coverage repeat_coverage repeat_modal_accuracy [exam] site 1.0 1.0 1.000000 [site] exam 1.0 1.0 0.666667Here every exam and site is observed, and all tested groups repeat. In a sparse
table, excluding missing targets can leave only singleton groups even when the
candidate repeated in the original table. determines_with_repeated_support
lists global exact targets that still have a repeated group after exclusions.
Check global_targets_tested against global_targets_possible before interpreting
an empty list. The sparse-target example
shows why exactness alone does not establish repeated agreement.
Check a grouping you already have in mind
Section titled “Check a grouping you already have in mind”When you already know the candidate keys, use grain to evaluate them directly:
exam_grain = fw.grain(df, candidate_keys=["exam"])print(fw.render_plaintext(exam_grain))Fieldwork · grainGrain (computed) Candidate keys exam: repeated grouping Observed dependencies among tested keys. exam [exam] -> site observed dependency holds; 0/3 violating groups; 0 affected rows support: 6 rows; 0 singleton, 3 repeated groups exam [exam] -> image_1 observed dependency fails; 3/3 violating groups; 6 affected rows support: 6 rows; 0 singleton, 3 repeated groups exam [exam] -> image_2 observed dependency fails; 3/3 violating groups; 6 affected rows support: 6 rows; 0 singleton, 3 repeated groups site: coarsest observed candidates: exam image_1: grain undetermined by supplied keys image_2: grain undetermined by supplied keysIf exam numbers restart at each site, declare a two-column key with fw.KeySpec("site_exam", ("site", "exam")). This treats site and exam together as the identifier.
Investigate disagreements
Section titled “Investigate disagreements”Larger datasets often have mappings that almost hold. discover_dependencies reports modal accuracy: the fraction of rows agreeing with the most common value in their group. For example, if 19 of 20 records agree, the accuracy is 95%.
Choose the relevant finding ID from the findings table, then pass it to dependencies.inspect(df, finding_id, exceptions=True, all_matches=True). The returned rows disagree with their group’s most common value; check the source before deciding whether they are errors.
The warehouse walkthrough works through this process, including a case where two columns are needed to identify a group. The argument reference covers search limits, missing values, and comparisons within contexts.