Different backend support with Ibis ๐ชฝ¶
icanexplain is implemented with Ibis. This means that it is framework agnostic, and can work with different backends. This example shows how to use it with DuckDB.
import ibis
import icanexplain as ice
products_df = ice.datasets.load_product_footprints()
con = ibis.connect("duckdb://example.ddb")
con.create_table(
"products", products_df, overwrite=True
)
DatabaseTable: example.main.products year int64 category string product_id string footprint float64 units int64
['products']
โโโโโโโโโณโโโโโโโโโโโณโโโโโโโโโโโโโณโโโโโโโโโโโโณโโโโโโโโ โ year โ category โ product_id โ footprint โ units โ โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ โ int64 โ string โ string โ float64 โ int64 โ โโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโค โ 2021 โ DRESS โ 848be709 โ 96.04 โ 803 โ โ 2021 โ DRESS โ 658f92b3 โ 58.15 โ 3367 โ โ 2021 โ DRESS โ 3a26f323 โ 82.94 โ 240 โ โ 2021 โ DRESS โ 6221dca6 โ 85.94 โ 432 โ โ 2021 โ DRESS โ 46864ac5 โ 84.99 โ 816 โ โโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโ
explainer = ice.SumExplainer(
fact='footprint',
count='units',
group='category',
period='year'
)
explanation = explainer(products)
explanation
โโโโโโโโโณโโโโโโโโโโโณโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโโโโ โ year โ category โ inner โ mix โ โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ โ int64 โ string โ float64 โ float64 โ โโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโค โ 2022 โ DRESS โ 3.931932e+06 โ -1.881370e+07 โ โ 2022 โ JACKET โ -1.510008e+07 โ -9.238617e+07 โ โ 2022 โ PANTS โ 4.002506e+07 โ 5.295190e+07 โ โ 2022 โ SHIRT โ -1.484809e+06 โ -5.791456e+06 โ โ 2022 โ SWEATER โ -2.676209e+07 โ 1.181504e+07 โ โ 2022 โ TSHIRT โ 6.650940e+06 โ -2.311836e+07 โ โ 2023 โ DRESS โ -4.078094e+06 โ -1.240339e+07 โ โ 2023 โ JACKET โ -6.793317e+06 โ -4.924036e+07 โ โ 2023 โ PANTS โ -1.636299e+07 โ -2.295608e+08 โ โ 2023 โ SHIRT โ 8.920908e+05 โ -4.019144e+06 โ โ โฆ โ โฆ โ โฆ โ โฆ โ โโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโ
ibis.expr.types.relations.Table
year | category | inner | mix | |
---|---|---|---|---|
0 | 2022 | DRESS | 3931932.447552 | -18813695.617552 |
1 | 2022 | JACKET | -15100081.026506 | -92386166.203493 |
2 | 2022 | PANTS | 40025058.515251 | 52951900.074743 |
3 | 2022 | SHIRT | -1484809.008950 | -5791455.871050 |
4 | 2022 | SWEATER | -26762091.196715 | 11815043.806715 |
5 | 2022 | TSHIRT | 6650940.137541 | -23118359.127541 |
6 | 2023 | DRESS | -4078094.357618 | -12403387.412381 |
7 | 2023 | JACKET | -6793316.568952 | -49240364.221049 |
8 | 2023 | PANTS | -16362993.150075 | -229560842.809919 |
9 | 2023 | SHIRT | 892090.812023 | -4019143.772023 |
10 | 2023 | SWEATER | -5701391.450394 | -113050731.029606 |
11 | 2023 | TSHIRT | -11503906.840478 | -83913226.849522 |
SELECT
*
FROM (
SELECT
"t9"."year",
"t9"."category",
"t9"."count_lag" * (
"t9"."mean" - "t9"."mean_lag"
) AS "inner",
(
"t9"."count" - "t9"."count_lag"
) * "t9"."mean" AS "mix"
FROM (
SELECT
"t8"."category",
"t8"."year",
"t8"."mean",
"t8"."count",
LAG("t8"."mean", 1) OVER (PARTITION BY "t8"."category" ORDER BY "t8"."year" ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "mean_lag",
LAG("t8"."count", 1) OVER (PARTITION BY "t8"."category" ORDER BY "t8"."year" ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "count_lag"
FROM (
SELECT
"t7"."category",
"t7"."year",
COALESCE("t7"."mean", 0) AS "mean",
COALESCE("t7"."count", 0) AS "count"
FROM (
SELECT
"t3"."category",
"t4"."year",
"t6"."mean",
"t6"."count"
FROM (
SELECT DISTINCT
"t0"."category"
FROM "products" AS "t0"
) AS "t3"
CROSS JOIN (
SELECT DISTINCT
"t0"."year"
FROM "products" AS "t0"
) AS "t4"
LEFT OUTER JOIN (
SELECT
"t0"."category",
"t0"."year",
SUM("t0"."footprint" * "t0"."units") / SUM("t0"."units") AS "mean",
SUM("t0"."units") AS "count"
FROM "products" AS "t0"
GROUP BY
1,
2
) AS "t6"
ON "t3"."category" = "t6"."category" AND "t4"."year" = "t6"."year"
) AS "t7"
) AS "t8"
) AS "t9"
ORDER BY
"t9"."year" ASC,
"t9"."category" ASC
) AS "t10"
WHERE
"t10"."year" IS NOT NULL
AND "t10"."category" IS NOT NULL
AND "t10"."inner" IS NOT NULL
AND "t10"."mix" IS NOT NULL