Skip to content

Results and configuration

Fieldwork returns a result that you can read, turn into a table, or save for later. For a step-by-step example, start with Save and compare.

Every analysis returns a fw.Result. It reads like a dictionary (result["scope"]), has a kind such as "missingness", "census" or "overview", and offers the same methods whatever produced it. Analyses such as missingness and discover_dependencies also save findings you can inspect and select; foundation analyses such as levels, census and grain hold counts and relationships, and their findings list is empty.

Interface Behavior
result.to_dict() A plain JSON-compatible dictionary for saving
fw.Result.from_dict(data) Restore a saved result (schema 2.0)
result.section(name) One section of an overview or profile, as its own Result
result.findings Findings; for an overview, its ranked leads resolved to full records
result.to_frame(section="findings") A dataframe of the chosen list, such as "availability"
result.inspect(df, finding, *, exceptions=False, all_matches=False) Saved representative source rows, or every matching row; a relation also takes side= and right=
result.select(df, finding, *, exceptions=False, name="finding selection") Every matching source row as a reusable Scope; a relation also takes side= and right=
result.recompute(df, **overrides) Rerun one analysis on its verified source with its saved settings; a relation between two tables also needs right=
result.relationships(feature=None, *, kinds=None) Feature connections and their supporting findings (overviews)
result.best, result.path(i) Ranked census paths of a paths result or overview; best may be None
fw.Scope.from_positions(df, positions, name=...) Save a row selection tied to the original dataframe
scope.refine(df, positions, name=...) Select fewer rows while recording the parent selection
fw.Recipe(operation, parameters={}, notes="") Save an operation and its JSON-compatible options
recipe.save(path), fw.Recipe.load(path), recipe.run(df, **overrides) Persist and reapply an investigation

Every result exports schema version 2.0, independent of the package version (0.3.2, an alpha). Values are plain JSON: null for every native missing spelling, numbers as numbers, infinities as "inf"/"-inf", and dates, datetimes and timedeltas as text that pandas parses back. Nested payload dictionaries are mutable.

result.recompute(df, limits={"example_limit": len(df)}) recovers more evidence from a single saved analysis. It restores the original parameters, missing conventions and scope, validates the source identity and reruns the analysis; a limits override merges with the saved budgets. Overview, profile and comparison results are compositions: recompute one of their sections instead.

Every analysis accepts the same source context:

  • scope: a reusable row selection tied to the original dataframe; default all rows.
  • missing: special missing-value codes for each column, such as {"reading": [-999]}; native missing values are always recognized.
  • table_id: nonempty table identity, default "table".

Discovery analyses also share:

  • features: columns to analyze; default all.
  • by: columns whose combinations define groups to analyze separately, such as site and season.
  • limits: a mapping of work and output budgets, such as {"max_candidates": 50, "example_limit": 10}. Omitted budgets keep their defaults; unknown names raise TypeError. The effective budgets are saved in result["parameters"]["limits"]. fieldwork.typing names the keys of each analysis: PathLimits, MissingnessLimits, DependencyLimits, PatternLimits and PairLimits.

Search limits are in coverage; display omissions are in the relevant result or renderer. An untested candidate has not failed a test. See Concepts for explanations and Measurement details for exact denominators and search order.

fw.explore(df) surveys a table. It takes features, by, the availability settings entity, unit and entity_presence, the sections to run, and per-section options, such as {"paths": {"objective": "compact"}, "dependencies": {"limits": {"max_candidates": 50}}}. A section’s limits merge with the overview’s defaults key by key. The overview stores each section’s result under sections and ranks their findings as leads; overview.findings resolves the leads to full records with IDs f0, f1, … in rank order.

fw.profile(df, dimensions) composes levels, a census, an optional grain and pairs for dimensions you choose. Census options go in census={...} and pair options in pairs={...} (or pairs=False); candidate_keys adds a grain section.

KeySpec(name, columns) names a key made from several columns; a saved {"name": ..., "columns": [...]} mapping is accepted wherever a KeySpec is. Census top_n_mode="post" counts the original population and limits the output; "pre" selects rows before counting, and a profile shares that selection with its pairs as a scope named “census top_n cohort”. Pair absence uses observed domains unless reference_domains declares alternatives. infer_schema produces role suggestions with evidence; it does not transform data.

Unknown columns raise KeyError; invalid limits, incompatible constraints, changed inspection sources and duplicate columns raise ValueError. Columns are identified by str(label), so integer or tuple labels work and are reported by their string form, which must be unique. Recipes permit only allowlisted operations (missingness, dependencies, paths, value_patterns, explore, profile, census, grain, levels, pairs, joint_counts, infer_schema and relate) and JSON-compatible parameters; recipe.run(left, right=right) supplies the right table of a relation, which a recipe never saves. Automatic multi-table discovery and branch-adaptive path orders are not implemented.

Complete selections and connected evidence

Section titled “Complete selections and connected evidence”

result.select(df, finding, *, exceptions=False, name="finding selection") saves every matching source row in a Scope, including the name of its parent selection. inspect(..., all_matches=True) returns those rows directly. Both check that the dataframe matches the original source and reuse the saved analysis settings. For an overview finding, Fieldwork uses the section that produced it. You can select signatures, contexts, and entity patterns even after saving and restoring the result.

overview.relationships(feature=None, *, kinds=None) returns typed feature connections and supporting evidence references. Connections retain their own counting units and populations. Connected components express reachability, not equivalence or a composed functional dependency.

paths.path(i).census(df) and paths.best.census(df) retain source scope and missing conventions, also after the result is saved and restored. The source must match; context overrides are rejected.

missingness accepts unit="rows" (default) or unit="entities", with entity_presence="any" (default) or "all" for entity units. Entity units require entity keys. analysis_unit records the denominator, eligible rows, and missing-key exclusions. Entity summaries classify raw-row any/all/one/some/none presence.

In an overview, entity, unit and entity_presence apply to the availability section; path, dependency and value-pattern evidence count rows. The shared features, by, scope, missing and table_id apply across sections.

Every result records one population shape. source names the dataset (dataset_id, table_id, rows, columns); scope records input_rows, evaluated_rows, restriction_excluded_rows and, for a scope, its name, parent and positions. Nested measurements carry their own evaluated_rows and missing_excluded_rows, plus restriction_excluded_rows where a context or pre-selection removed rows.

to_dict() returns plain JSON-compatible data; restore it with fw.Result.from_dict. Findings and dependency grain views store at most example_limit source positions each, so saved results do not grow with the number of rows for those records. A grain view records its anchor_candidate_id, whose complete cases define the view’s population, and bounded population.examples.

Results saved by 0.2.x or earlier (schemas 0.3 and 1.0) no longer load: from_dict raises ValueError. Rerun the analysis with 0.3.x; a saved Recipe still records the settings, though recipes that used removed or renamed options need updating.

to_frame("dependencies") exposes all completed target tests, including tests below min_accuracy. to_frame("candidates") includes global exact targets, repeat-supported exact targets and completed/possible global test counters.

All dataframe analyses and source inspection/selection methods accept progress, cancel, timeout and safe_errors. These runtime objects are not saved in recipes or results. Pass them to Recipe.run when executing. See runtime controls for callback fields, cancellation, work budgets and their limits.

Editors expose public signatures and NumPy-style docstrings. fieldwork.typing exports reusable dictionary types: SectionOptions for an overview’s options, per-section option types, CensusOptions and PairOptions for profile, and the limits types above. They are ordinary dictionaries, not runtime validation models. Returned paths expose dimensions and census with source-preserving signatures; passing source context to Path.census raises TypeError.