Retrieving and Querying Splink Results¶
When Splink returns results, it does so in the format of a SplinkDataFrame. This is needed to allow Splink to provide results in a uniform format across the different database backends
For example, when you run df_predict = linker.inference.predict(), the result df_predict is a SplinkDataFrame.
A SplinkDataFrame is an abstraction of a table in the underlying backend database, and provides several convenience methods for interacting with the underlying table.
For detailed information check the full API.
Converting to other types¶
You can convert a SplinkDataFrame into a variety of types. You will usually get best performance by using the backends native types e.g.:
- For DuckDB, use
splink_df.as_duckdbpyrelation()to obtain aDuckDBPyRelation - For Spark, use
splink_df.as_spark_dataframe()to obtain a Spark `
You can also convert a SplinkDataFrame into other types, including:
- a PyArrow Table, using
splink_df.as_pyarrow_table() - a Pandas dataframe, using
splink_df.as_pandas_dataframe() - a list of record dictionaries, using
splink_df.as_record_list()
For large linkages, it is not recommended to convert the whole SplinkDataFrame into an in-memory type because Splink results can be very large, so doing so can be slow and result in out of memory errors. Usually it will be better to use SQL to query the tables directly.
Querying tables¶
You can run SQL queries directly against a SplinkDataFrame using its query_sql method, referring to the table within your SQL as {this}. This is the recommended approach as it's typically faster and more memory efficient than using pandas dataframes. If you need the underlying table name directly, you can find it using splink_df.physical_name.
The following is an example of this approach, in which we use SQL to find the best match to each input record in a link_type="link_only" job (i.e remove duplicate matches):
# linker is a Linker with link_type set to "link_only"
df_predict = linker.inference.predict(threshold_match_probability=0.75)
sql = """
with ranked as
(
select *,
row_number() OVER (
PARTITION BY unique_id_l order by match_weight desc
) as row_number
from {this}
)
select *
from ranked
where row_number = 1
"""
df_query_result = df_predict.query_sql(sql) # SplinkDataFrame
query_sql returns a SplinkDataFrame. If you want the results as a pandas dataframe, convert it as follows:
df_query_result = df_predict.query_sql(sql).as_pandas_dataframe()
Saving results¶
If you have a SplinkDataFrame, you may wish to store the results in some file outside of your database.
As tables may be large, there are a couple of convenience methods for doing this directly without needing to load the table into memory.
Currently Splink supports saving frames to either csv or parquet format.
Of these we generally recommend the latter, as it is typed, compressed, column-oriented, and easily supports nested data.
To save results, simply use the methods to_csv() or to_parquet() - for example:
df_predict = linker.inference.predict()
df_predict.to_parquet("splink_predictions.parquet", overwrite=True)
# or alternatively:
df_predict.to_csv("splink_predictions.csv", overwrite=True)
Creating a SplinkDataFrame¶
You can create a SplinkDataFrame for any table in your database using db_api.register; a Linker is not required:
import duckdb
import pyarrow as pa
from splink import DuckDBAPI
con = duckdb.connect()
arrow_numbers = pa.Table.from_pydict({"id": [1, 2, 3], "number": ["one", "two", "three"]})
con.sql("CREATE TABLE number_table AS SELECT * FROM arrow_numbers")
db_api = DuckDBAPI(connection=con)
splink_df = db_api.register("number_table")
splink_df.as_record_list()