Omniscope Custom Blocks › Preparation/Smart-Schema-Normaliser

Smart Schema Normaliser

Cleans up an export with untidy field names: makes the names lower case with underscores, merges fields whose names differ only in case, spaces or dashes, and gives each text field a number, date, yes/no or text type, working through the data in chunks so large inputs never have to fit in memory.

Preparation Python

Open the demo in Omniscope Download demo.ioz Sample data: customer-exports.csv Source on GitHub

Omniscope custom block · Preparation

The same field under two names, numbers stored as text, yes written four ways? One tidy field per name, with a sensible type, and no list of fields to keep up to date.

Python · pandas · nothing extra to install

The problem it solves

A customer list comes from two systems appended together. One system calls the ID Customer ID and the spend Monthly Spend; the other writes customer_id and monthly-spend. Each record has its value in one field or the other, sign-up dates are in two formats, one order count reads unknown, and the active flag is yes, Y, n or Yes.

This block merges the fields that differ only in how their names are written, and gives each text field the type most of its values fit.

How it works

What goes in

Customer exports

12 invented customers from two systems, appended into one table.

Customer ID customer_id Name Sign-up Date Monthly Spend monthly-spend Orders Active
C-001 Ashdown Bakery 2024-01-15 120.50 14 yes
C-002 Brindle and Co 15/02/2024 89.00 9 no
C-003 Corve Valley Farm 2024-03-02 240.00 22 Y
C-004 Dunmore Joinery 04/03/2024 56.25 unknown N
C-007 C-007 Glenrock Outdoor 2024-05-06 198.00 198.00 19 yes
C-008 Hollin Tea Rooms 64.80 5
C-009 Ivybridge Print 2024-06-21 3 n

12 rows and a Region field in the sample file.

The options

Option Demo setting What it does
Prefer non-empty values ticked Empty text counts as missing when merging.
Sort fields by name unticked Fields keep the order in which they first appear.
Auto cast threshold 0.9 11 of 12 order counts are numbers (92%), enough for an Integer field. At the default 0.98 the field stays text.
Day first ticked 04/03/2024 is 4 March.
Defaults for missing numbers, dates, text empty Missing values stay missing.

What comes out

Normalised customers (selected records)

customer_id name sign_up_date monthly_spend orders active region
C-001 Ashdown Bakery 2024-01-15 120.50 14 true South East
C-002 Brindle and Co 2024-02-15 89.00 9 false North West
C-003 Corve Valley Farm 2024-03-02 240.00 22 true West Midlands
C-004 Dunmore Joinery 2024-03-04 56.25 false Scotland
C-008 Hollin Tea Rooms 64.80 5 Yorkshire
C-009 Ivybridge Print 2024-06-21 3 false South West

12 records, 7 fields: sign_up_date is a Date, monthly_spend a Decimal, orders an Integer and active yes/no. C-009's spend is missing in both source fields and stays empty rather than becoming 0.

Where it pays off

Data integration: Appending exports from several systems

Bring customer, product or order lists from two systems into one table without first renaming every field by hand.

Spreadsheets: Hand-kept lists

Lists kept by several people collect near-duplicate columns and numbers typed as text; tidy them before joining or charting.

Recurring feeds: New and renamed fields

A supplier feed that adds a field or changes its capitalisation still comes out with predictable names, so the blocks after it keep working.

Data exploration: First look at an unknown file

Turn off the File block's type detection and let this block propose types, then check the result in a Data Profiler.

Use cases describe typical scenarios and are illustrative; the sample data is invented.

Why do this in Omniscope

How it fits into an Omniscope workflow

System A export, System B export (File) → Append → Smart Schema Normaliser → Validate data → Aggregate → Report

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder): 12 customers from two systems.
  2. The question: what does each region spend per month?
  3. Open Smart Schema Normaliser: threshold 0.9, Day first ticked. Run it.
  4. Look at the output: 7 fields, one ID and one spend for every customer, sign_up_date as a Date.
  5. Set the threshold back to 0.98 and run again: orders stays text because of the one unknown.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses pandas.

pandas is part of Omniscope's Python environment. It needs nothing else installed.

Tested

The block is covered by automated tests that run its script against a stand-in for Omniscope's Python API: the sample data, the default threshold, missing values not counted against the threshold, defaults for missing values, Date and number fields kept, leading zeros, words that look like months, merging with and without empty values, sorting, empty input, bad options, types decided by the first chunk and kept (with the values that don't fit counted), and 200,000 records. On an Omniscope server it streamed 300,000 records with the late misfits counted and left empty.

Reference

Options

NameTypeWhat it does
Prefer non-empty valuesYes / noWhen merging fields, an empty text value is replaced by the next field's value, like a missing one.
Sort fields by nameYes / noOrder the output fields alphabetically. Unticked, they keep the order of their first appearance.
Auto cast thresholdNumberShare of a field's values (0 to 1, missing values not counted) that must fit a type for the field to get it. Default 0.98.
Day firstYes / noRead ambiguous dates such as 04/03/2024 as 4 March. Unticked, 3 April. Dates starting with a four-digit year are always year-month-day.
Default for missing numbersTextOptional. A number (such as 0) to put in empty values of number fields. Empty: they stay missing.
Default for missing datesTextOptional. A date (such as 1970-01-01) to put in empty values of date fields. Empty: they stay missing.
Default for missing textTextOptional. Text to put in empty values of text fields. Empty: they stay missing.

Outputs

OutputWhat it holds
NormalisedThe input with tidied field names, merged duplicate fields and inferred types.