post-analysis-toolkit 1.0.2__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {post_analysis_toolkit-1.0.2/post_analysis_toolkit.egg-info → post_analysis_toolkit-1.0.4}/PKG-INFO +2 -2
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/notebooks/did_its_template.ipynb +114 -64
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/README.md +1 -1
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/__init__.py +1 -1
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/causal_impact.py +18 -2
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/did.py +32 -1
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/its.py +3 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/visualization.py +28 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4/post_analysis_toolkit.egg-info}/PKG-INFO +2 -2
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/pyproject.toml +1 -1
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/MANIFEST.in +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/README.md +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/MDE_METHODOLOGY.md +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/REFERENCE.html +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/REFERENCE.md +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/compat.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/contracts.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/demo.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/mde.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/mde_resampling.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/observational.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/rdd.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/synthetic_control.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/triple_difference.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/utils.py +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit.egg-info/SOURCES.txt +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit.egg-info/dependency_links.txt +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit.egg-info/requires.txt +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit.egg-info/top_level.txt +0 -0
- {post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/setup.cfg +0 -0
{post_analysis_toolkit-1.0.2/post_analysis_toolkit.egg-info → post_analysis_toolkit-1.0.4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: post-analysis-toolkit
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Reusable helpers for post-analysis, quasi-causal designs, and diagnostics.
|
|
5
5
|
Author: OpenAI Codex
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -1151,4 +1151,4 @@ its_result = fit_its(
|
|
|
1151
1151
|
|
|
1152
1152
|
## Версия
|
|
1153
1153
|
|
|
1154
|
-
Текущая версия пакета: `1.0.
|
|
1154
|
+
Текущая версия пакета: `1.0.4`
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/notebooks/did_its_template.ipynb
RENAMED
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"id": "979f6a5a",
|
|
35
35
|
"metadata": {
|
|
36
36
|
"execution": {
|
|
37
|
-
"iopub.execute_input": "2026-08-
|
|
38
|
-
"iopub.status.busy": "2026-08-
|
|
39
|
-
"iopub.status.idle": "2026-08-
|
|
40
|
-
"shell.execute_reply": "2026-08-
|
|
37
|
+
"iopub.execute_input": "2026-08-19T05:10:57.124787Z",
|
|
38
|
+
"iopub.status.busy": "2026-08-19T05:10:57.124594Z",
|
|
39
|
+
"iopub.status.idle": "2026-08-19T05:11:00.044911Z",
|
|
40
|
+
"shell.execute_reply": "2026-08-19T05:11:00.044081Z"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"outputs": [],
|
|
@@ -106,10 +106,10 @@
|
|
|
106
106
|
"id": "187f6644",
|
|
107
107
|
"metadata": {
|
|
108
108
|
"execution": {
|
|
109
|
-
"iopub.execute_input": "2026-08-
|
|
110
|
-
"iopub.status.busy": "2026-08-
|
|
111
|
-
"iopub.status.idle": "2026-08-
|
|
112
|
-
"shell.execute_reply": "2026-08-
|
|
109
|
+
"iopub.execute_input": "2026-08-19T05:11:00.046648Z",
|
|
110
|
+
"iopub.status.busy": "2026-08-19T05:11:00.046396Z",
|
|
111
|
+
"iopub.status.idle": "2026-08-19T05:11:00.061703Z",
|
|
112
|
+
"shell.execute_reply": "2026-08-19T05:11:00.061146Z"
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
115
|
"outputs": [
|
|
@@ -210,10 +210,10 @@
|
|
|
210
210
|
"id": "52678d87",
|
|
211
211
|
"metadata": {
|
|
212
212
|
"execution": {
|
|
213
|
-
"iopub.execute_input": "2026-08-
|
|
214
|
-
"iopub.status.busy": "2026-08-
|
|
215
|
-
"iopub.status.idle": "2026-08-
|
|
216
|
-
"shell.execute_reply": "2026-08-
|
|
213
|
+
"iopub.execute_input": "2026-08-19T05:11:00.063608Z",
|
|
214
|
+
"iopub.status.busy": "2026-08-19T05:11:00.063363Z",
|
|
215
|
+
"iopub.status.idle": "2026-08-19T05:11:03.162282Z",
|
|
216
|
+
"shell.execute_reply": "2026-08-19T05:11:03.161245Z"
|
|
217
217
|
}
|
|
218
218
|
},
|
|
219
219
|
"outputs": [
|
|
@@ -323,6 +323,24 @@
|
|
|
323
323
|
},
|
|
324
324
|
"metadata": {},
|
|
325
325
|
"output_type": "display_data"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"data": {
|
|
329
|
+
"text/plain": [
|
|
330
|
+
"<Figure size 1800x400 with 3 Axes>"
|
|
331
|
+
]
|
|
332
|
+
},
|
|
333
|
+
"metadata": {},
|
|
334
|
+
"output_type": "display_data"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"data": {
|
|
338
|
+
"text/plain": [
|
|
339
|
+
"<Figure size 1000x400 with 1 Axes>"
|
|
340
|
+
]
|
|
341
|
+
},
|
|
342
|
+
"metadata": {},
|
|
343
|
+
"output_type": "display_data"
|
|
326
344
|
}
|
|
327
345
|
],
|
|
328
346
|
"source": [
|
|
@@ -336,7 +354,9 @@
|
|
|
336
354
|
" unit_col=\"pizzeria\",\n",
|
|
337
355
|
" fpr_placebo_count=200,\n",
|
|
338
356
|
")\n",
|
|
339
|
-
"display(show_checks(did_diagnostics.checks))"
|
|
357
|
+
"display(show_checks(did_diagnostics.checks))\n",
|
|
358
|
+
"display(did_diagnostics.figures[\"pretrend_triptych\"])\n",
|
|
359
|
+
"display(did_diagnostics.figures[\"event_study\"])"
|
|
340
360
|
]
|
|
341
361
|
},
|
|
342
362
|
{
|
|
@@ -345,10 +365,10 @@
|
|
|
345
365
|
"id": "c8f0a026",
|
|
346
366
|
"metadata": {
|
|
347
367
|
"execution": {
|
|
348
|
-
"iopub.execute_input": "2026-08-
|
|
349
|
-
"iopub.status.busy": "2026-08-
|
|
350
|
-
"iopub.status.idle": "2026-08-
|
|
351
|
-
"shell.execute_reply": "2026-08-
|
|
368
|
+
"iopub.execute_input": "2026-08-19T05:11:03.164560Z",
|
|
369
|
+
"iopub.status.busy": "2026-08-19T05:11:03.164357Z",
|
|
370
|
+
"iopub.status.idle": "2026-08-19T05:11:03.237609Z",
|
|
371
|
+
"shell.execute_reply": "2026-08-19T05:11:03.236585Z"
|
|
352
372
|
}
|
|
353
373
|
},
|
|
354
374
|
"outputs": [
|
|
@@ -1527,6 +1547,15 @@
|
|
|
1527
1547
|
},
|
|
1528
1548
|
"metadata": {},
|
|
1529
1549
|
"output_type": "display_data"
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
"data": {
|
|
1553
|
+
"text/plain": [
|
|
1554
|
+
"<Figure size 1200x400 with 1 Axes>"
|
|
1555
|
+
]
|
|
1556
|
+
},
|
|
1557
|
+
"metadata": {},
|
|
1558
|
+
"output_type": "display_data"
|
|
1530
1559
|
}
|
|
1531
1560
|
],
|
|
1532
1561
|
"source": [
|
|
@@ -1541,7 +1570,8 @@
|
|
|
1541
1570
|
" **MDE_SETTINGS,\n",
|
|
1542
1571
|
")\n",
|
|
1543
1572
|
"display(show_summary(did_result.summary))\n",
|
|
1544
|
-
"display(show_frame(did_result.details[\"coefficients\"]))"
|
|
1573
|
+
"display(show_frame(did_result.details[\"coefficients\"]))\n",
|
|
1574
|
+
"display(did_result.figures[\"did_effect\"])"
|
|
1545
1575
|
]
|
|
1546
1576
|
},
|
|
1547
1577
|
{
|
|
@@ -1560,10 +1590,10 @@
|
|
|
1560
1590
|
"id": "6ff8ba4a",
|
|
1561
1591
|
"metadata": {
|
|
1562
1592
|
"execution": {
|
|
1563
|
-
"iopub.execute_input": "2026-08-
|
|
1564
|
-
"iopub.status.busy": "2026-08-
|
|
1565
|
-
"iopub.status.idle": "2026-08-
|
|
1566
|
-
"shell.execute_reply": "2026-08-
|
|
1593
|
+
"iopub.execute_input": "2026-08-19T05:11:03.239531Z",
|
|
1594
|
+
"iopub.status.busy": "2026-08-19T05:11:03.239433Z",
|
|
1595
|
+
"iopub.status.idle": "2026-08-19T05:11:03.242564Z",
|
|
1596
|
+
"shell.execute_reply": "2026-08-19T05:11:03.241766Z"
|
|
1567
1597
|
}
|
|
1568
1598
|
},
|
|
1569
1599
|
"outputs": [
|
|
@@ -1599,10 +1629,10 @@
|
|
|
1599
1629
|
"id": "523adfbb",
|
|
1600
1630
|
"metadata": {
|
|
1601
1631
|
"execution": {
|
|
1602
|
-
"iopub.execute_input": "2026-08-
|
|
1603
|
-
"iopub.status.busy": "2026-08-
|
|
1604
|
-
"iopub.status.idle": "2026-08-
|
|
1605
|
-
"shell.execute_reply": "2026-08-
|
|
1632
|
+
"iopub.execute_input": "2026-08-19T05:11:03.244624Z",
|
|
1633
|
+
"iopub.status.busy": "2026-08-19T05:11:03.244433Z",
|
|
1634
|
+
"iopub.status.idle": "2026-08-19T05:11:03.528854Z",
|
|
1635
|
+
"shell.execute_reply": "2026-08-19T05:11:03.528266Z"
|
|
1606
1636
|
}
|
|
1607
1637
|
},
|
|
1608
1638
|
"outputs": [
|
|
@@ -1729,10 +1759,10 @@
|
|
|
1729
1759
|
"id": "87833fe4",
|
|
1730
1760
|
"metadata": {
|
|
1731
1761
|
"execution": {
|
|
1732
|
-
"iopub.execute_input": "2026-08-
|
|
1733
|
-
"iopub.status.busy": "2026-08-
|
|
1734
|
-
"iopub.status.idle": "2026-08-
|
|
1735
|
-
"shell.execute_reply": "2026-08-
|
|
1762
|
+
"iopub.execute_input": "2026-08-19T05:11:03.531370Z",
|
|
1763
|
+
"iopub.status.busy": "2026-08-19T05:11:03.531223Z",
|
|
1764
|
+
"iopub.status.idle": "2026-08-19T05:11:03.537615Z",
|
|
1765
|
+
"shell.execute_reply": "2026-08-19T05:11:03.536709Z"
|
|
1736
1766
|
}
|
|
1737
1767
|
},
|
|
1738
1768
|
"outputs": [
|
|
@@ -1810,10 +1840,10 @@
|
|
|
1810
1840
|
"id": "ebf028ab",
|
|
1811
1841
|
"metadata": {
|
|
1812
1842
|
"execution": {
|
|
1813
|
-
"iopub.execute_input": "2026-08-
|
|
1814
|
-
"iopub.status.busy": "2026-08-
|
|
1815
|
-
"iopub.status.idle": "2026-08-
|
|
1816
|
-
"shell.execute_reply": "2026-08-
|
|
1843
|
+
"iopub.execute_input": "2026-08-19T05:11:03.539639Z",
|
|
1844
|
+
"iopub.status.busy": "2026-08-19T05:11:03.539467Z",
|
|
1845
|
+
"iopub.status.idle": "2026-08-19T05:11:06.924485Z",
|
|
1846
|
+
"shell.execute_reply": "2026-08-19T05:11:06.923547Z"
|
|
1817
1847
|
}
|
|
1818
1848
|
},
|
|
1819
1849
|
"outputs": [
|
|
@@ -1951,6 +1981,15 @@
|
|
|
1951
1981
|
},
|
|
1952
1982
|
"metadata": {},
|
|
1953
1983
|
"output_type": "display_data"
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
"data": {
|
|
1987
|
+
"text/plain": [
|
|
1988
|
+
"<Figure size 1200x400 with 1 Axes>"
|
|
1989
|
+
]
|
|
1990
|
+
},
|
|
1991
|
+
"metadata": {},
|
|
1992
|
+
"output_type": "display_data"
|
|
1954
1993
|
}
|
|
1955
1994
|
],
|
|
1956
1995
|
"source": [
|
|
@@ -1961,7 +2000,8 @@
|
|
|
1961
2000
|
" intervention_time=INTERVENTION_TIME,\n",
|
|
1962
2001
|
" fpr_placebo_count=200,\n",
|
|
1963
2002
|
")\n",
|
|
1964
|
-
"display(show_checks(its_diagnostics.checks))"
|
|
2003
|
+
"display(show_checks(its_diagnostics.checks))\n",
|
|
2004
|
+
"display(its_diagnostics.figures[\"pre_fit\"])"
|
|
1965
2005
|
]
|
|
1966
2006
|
},
|
|
1967
2007
|
{
|
|
@@ -1970,10 +2010,10 @@
|
|
|
1970
2010
|
"id": "50affca8",
|
|
1971
2011
|
"metadata": {
|
|
1972
2012
|
"execution": {
|
|
1973
|
-
"iopub.execute_input": "2026-08-
|
|
1974
|
-
"iopub.status.busy": "2026-08-
|
|
1975
|
-
"iopub.status.idle": "2026-08-
|
|
1976
|
-
"shell.execute_reply": "2026-08-
|
|
2013
|
+
"iopub.execute_input": "2026-08-19T05:11:06.925931Z",
|
|
2014
|
+
"iopub.status.busy": "2026-08-19T05:11:06.925795Z",
|
|
2015
|
+
"iopub.status.idle": "2026-08-19T05:11:06.996372Z",
|
|
2016
|
+
"shell.execute_reply": "2026-08-19T05:11:06.995573Z"
|
|
1977
2017
|
}
|
|
1978
2018
|
},
|
|
1979
2019
|
"outputs": [
|
|
@@ -2257,10 +2297,10 @@
|
|
|
2257
2297
|
"id": "9c501c9b",
|
|
2258
2298
|
"metadata": {
|
|
2259
2299
|
"execution": {
|
|
2260
|
-
"iopub.execute_input": "2026-08-
|
|
2261
|
-
"iopub.status.busy": "2026-08-
|
|
2262
|
-
"iopub.status.idle": "2026-08-
|
|
2263
|
-
"shell.execute_reply": "2026-08-
|
|
2300
|
+
"iopub.execute_input": "2026-08-19T05:11:06.998607Z",
|
|
2301
|
+
"iopub.status.busy": "2026-08-19T05:11:06.998379Z",
|
|
2302
|
+
"iopub.status.idle": "2026-08-19T05:11:07.002063Z",
|
|
2303
|
+
"shell.execute_reply": "2026-08-19T05:11:07.001109Z"
|
|
2264
2304
|
}
|
|
2265
2305
|
},
|
|
2266
2306
|
"outputs": [
|
|
@@ -2296,10 +2336,10 @@
|
|
|
2296
2336
|
"id": "5bd00664",
|
|
2297
2337
|
"metadata": {
|
|
2298
2338
|
"execution": {
|
|
2299
|
-
"iopub.execute_input": "2026-08-
|
|
2300
|
-
"iopub.status.busy": "2026-08-
|
|
2301
|
-
"iopub.status.idle": "2026-08-
|
|
2302
|
-
"shell.execute_reply": "2026-08-
|
|
2339
|
+
"iopub.execute_input": "2026-08-19T05:11:07.004105Z",
|
|
2340
|
+
"iopub.status.busy": "2026-08-19T05:11:07.003957Z",
|
|
2341
|
+
"iopub.status.idle": "2026-08-19T05:11:07.272721Z",
|
|
2342
|
+
"shell.execute_reply": "2026-08-19T05:11:07.271568Z"
|
|
2303
2343
|
}
|
|
2304
2344
|
},
|
|
2305
2345
|
"outputs": [
|
|
@@ -2470,10 +2510,10 @@
|
|
|
2470
2510
|
"id": "015ecfd6",
|
|
2471
2511
|
"metadata": {
|
|
2472
2512
|
"execution": {
|
|
2473
|
-
"iopub.execute_input": "2026-08-
|
|
2474
|
-
"iopub.status.busy": "2026-08-
|
|
2475
|
-
"iopub.status.idle": "2026-08-
|
|
2476
|
-
"shell.execute_reply": "2026-08-
|
|
2513
|
+
"iopub.execute_input": "2026-08-19T05:11:07.274753Z",
|
|
2514
|
+
"iopub.status.busy": "2026-08-19T05:11:07.274601Z",
|
|
2515
|
+
"iopub.status.idle": "2026-08-19T05:11:09.908425Z",
|
|
2516
|
+
"shell.execute_reply": "2026-08-19T05:11:09.907535Z"
|
|
2477
2517
|
}
|
|
2478
2518
|
},
|
|
2479
2519
|
"outputs": [
|
|
@@ -2597,6 +2637,15 @@
|
|
|
2597
2637
|
},
|
|
2598
2638
|
"metadata": {},
|
|
2599
2639
|
"output_type": "display_data"
|
|
2640
|
+
},
|
|
2641
|
+
{
|
|
2642
|
+
"data": {
|
|
2643
|
+
"text/plain": [
|
|
2644
|
+
"<Figure size 1200x400 with 1 Axes>"
|
|
2645
|
+
]
|
|
2646
|
+
},
|
|
2647
|
+
"metadata": {},
|
|
2648
|
+
"output_type": "display_data"
|
|
2600
2649
|
}
|
|
2601
2650
|
],
|
|
2602
2651
|
"source": [
|
|
@@ -2610,7 +2659,8 @@
|
|
|
2610
2659
|
" max_controls=4,\n",
|
|
2611
2660
|
" fpr_placebo_count=200,\n",
|
|
2612
2661
|
")\n",
|
|
2613
|
-
"display(show_checks(causal_impact_assumptions.checks))"
|
|
2662
|
+
"display(show_checks(causal_impact_assumptions.checks))\n",
|
|
2663
|
+
"display(causal_impact_assumptions.figures[\"pre_fit\"])"
|
|
2614
2664
|
]
|
|
2615
2665
|
},
|
|
2616
2666
|
{
|
|
@@ -2619,10 +2669,10 @@
|
|
|
2619
2669
|
"id": "f71db402",
|
|
2620
2670
|
"metadata": {
|
|
2621
2671
|
"execution": {
|
|
2622
|
-
"iopub.execute_input": "2026-08-
|
|
2623
|
-
"iopub.status.busy": "2026-08-
|
|
2624
|
-
"iopub.status.idle": "2026-08-
|
|
2625
|
-
"shell.execute_reply": "2026-08-
|
|
2672
|
+
"iopub.execute_input": "2026-08-19T05:11:09.910444Z",
|
|
2673
|
+
"iopub.status.busy": "2026-08-19T05:11:09.910270Z",
|
|
2674
|
+
"iopub.status.idle": "2026-08-19T05:11:09.990487Z",
|
|
2675
|
+
"shell.execute_reply": "2026-08-19T05:11:09.989567Z"
|
|
2626
2676
|
}
|
|
2627
2677
|
},
|
|
2628
2678
|
"outputs": [
|
|
@@ -2916,10 +2966,10 @@
|
|
|
2916
2966
|
"id": "2eec09cf",
|
|
2917
2967
|
"metadata": {
|
|
2918
2968
|
"execution": {
|
|
2919
|
-
"iopub.execute_input": "2026-08-
|
|
2920
|
-
"iopub.status.busy": "2026-08-
|
|
2921
|
-
"iopub.status.idle": "2026-08-
|
|
2922
|
-
"shell.execute_reply": "2026-08-
|
|
2969
|
+
"iopub.execute_input": "2026-08-19T05:11:09.992523Z",
|
|
2970
|
+
"iopub.status.busy": "2026-08-19T05:11:09.992414Z",
|
|
2971
|
+
"iopub.status.idle": "2026-08-19T05:11:09.995718Z",
|
|
2972
|
+
"shell.execute_reply": "2026-08-19T05:11:09.995173Z"
|
|
2923
2973
|
}
|
|
2924
2974
|
},
|
|
2925
2975
|
"outputs": [
|
|
@@ -2956,10 +3006,10 @@
|
|
|
2956
3006
|
"id": "eb6ee5b7",
|
|
2957
3007
|
"metadata": {
|
|
2958
3008
|
"execution": {
|
|
2959
|
-
"iopub.execute_input": "2026-08-
|
|
2960
|
-
"iopub.status.busy": "2026-08-
|
|
2961
|
-
"iopub.status.idle": "2026-08-
|
|
2962
|
-
"shell.execute_reply": "2026-08-
|
|
3009
|
+
"iopub.execute_input": "2026-08-19T05:11:09.997830Z",
|
|
3010
|
+
"iopub.status.busy": "2026-08-19T05:11:09.997647Z",
|
|
3011
|
+
"iopub.status.idle": "2026-08-19T05:11:10.919476Z",
|
|
3012
|
+
"shell.execute_reply": "2026-08-19T05:11:10.918196Z"
|
|
2963
3013
|
}
|
|
2964
3014
|
},
|
|
2965
3015
|
"outputs": [
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/causal_impact.py
RENAMED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from collections.abc import Iterable
|
|
4
4
|
from contextlib import redirect_stdout
|
|
5
5
|
import io
|
|
6
|
+
import warnings
|
|
6
7
|
|
|
7
8
|
import numpy as np
|
|
8
9
|
import pandas as pd
|
|
@@ -159,6 +160,8 @@ def _causal_impact_placebo_fpr(
|
|
|
159
160
|
alpha: float = 0.05,
|
|
160
161
|
) -> tuple[int, int]:
|
|
161
162
|
dates = sorted(pd.to_datetime(df[time_col]).drop_duplicates())
|
|
163
|
+
if placebo_count <= 0:
|
|
164
|
+
return 0, 0
|
|
162
165
|
pre_dates = [date for date in dates if date < intervention_time]
|
|
163
166
|
placebo_dates = [
|
|
164
167
|
date for date in pre_dates
|
|
@@ -189,6 +192,7 @@ def _causal_impact_placebo_fpr(
|
|
|
189
192
|
upper = float(result.summary.iloc[0]["average_abs_effect_upper"])
|
|
190
193
|
interval_low, interval_high = sorted((lower, upper)) if np.isfinite(lower) and np.isfinite(upper) else (np.nan, np.nan)
|
|
191
194
|
significant = (np.isfinite(tail_area) and tail_area < alpha) or (np.isfinite(interval_low) and np.isfinite(interval_high) and (interval_low > 0 or interval_high < 0))
|
|
195
|
+
close_method_result_figures(result)
|
|
192
196
|
if np.isfinite(tail_area) or (np.isfinite(lower) and np.isfinite(upper)):
|
|
193
197
|
runs += 1
|
|
194
198
|
false_positives += int(significant)
|
|
@@ -430,8 +434,20 @@ def fit_causal_impact(
|
|
|
430
434
|
_ensure_nonempty_analysis_periods(ci_df, pre_period, post_period)
|
|
431
435
|
|
|
432
436
|
validation_stats = _split_pre_validation(ci_df, pre_period)
|
|
433
|
-
|
|
434
|
-
|
|
437
|
+
# statsmodels' HP filter emits a harmless SparseEfficiencyWarning on
|
|
438
|
+
# Databricks' scipy/statsmodels combinations. CausalImpact does not
|
|
439
|
+
# expose the HP-filter matrix, so there is no actionable input here;
|
|
440
|
+
# suppress only this narrowly identified warning around the third-party
|
|
441
|
+
# model execution (including placebo/robustness calls through this
|
|
442
|
+
# function).
|
|
443
|
+
with warnings.catch_warnings():
|
|
444
|
+
warnings.filterwarnings(
|
|
445
|
+
"ignore",
|
|
446
|
+
message=r"spsolve requires A be CSC or CSR matrix format",
|
|
447
|
+
module=r"statsmodels\.tsa\.filters\.hp_filter",
|
|
448
|
+
)
|
|
449
|
+
ci_model = CausalImpact(ci_df, list(pre_period), list(post_period))
|
|
450
|
+
ci_model.run()
|
|
435
451
|
summary = _extract_ci_summary(ci_model, post_period)
|
|
436
452
|
post_obs = int(((ci_df.index >= pd.Timestamp(post_period[0])) & (ci_df.index <= pd.Timestamp(post_period[1]))).sum())
|
|
437
453
|
baseline = float(ci_df.loc[(ci_df.index >= pd.Timestamp(pre_period[0])) & (ci_df.index <= pd.Timestamp(pre_period[1])), "y"].mean())
|
|
@@ -43,7 +43,7 @@ from post_analysis_toolkit.utils import (
|
|
|
43
43
|
safe_corr,
|
|
44
44
|
restrict_to_pre_period_window,
|
|
45
45
|
)
|
|
46
|
-
from post_analysis_toolkit.visualization import plot_estimate_series, plot_event_study, plot_pretrend_triptych
|
|
46
|
+
from post_analysis_toolkit.visualization import plot_did_effect, plot_estimate_series, plot_event_study, plot_pretrend_triptych
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def _prepare_did_data(
|
|
@@ -420,6 +420,26 @@ def fit_did_regression(
|
|
|
420
420
|
.sort_values("term")
|
|
421
421
|
.reset_index(drop=True)
|
|
422
422
|
)
|
|
423
|
+
grouped = (
|
|
424
|
+
work_df.assign(_time=pd.to_datetime(work_df[time_col]))
|
|
425
|
+
.groupby(["_time", treated_col], as_index=False)[analysis_outcome_col]
|
|
426
|
+
.mean()
|
|
427
|
+
)
|
|
428
|
+
treated_series = grouped.loc[grouped[treated_col].astype(int) == 1, ["_time", analysis_outcome_col]].rename(columns={analysis_outcome_col: "treated_actual"})
|
|
429
|
+
control_series = grouped.loc[grouped[treated_col].astype(int) == 0, ["_time", analysis_outcome_col]].rename(columns={analysis_outcome_col: "control_actual"})
|
|
430
|
+
did_series = treated_series.merge(control_series, on="_time", how="outer").sort_values("_time")
|
|
431
|
+
intervention_ts = pd.Timestamp(work_df.loc[work_df[post_col].astype(int) == 1, time_col].min()) if post_obs else None
|
|
432
|
+
if intervention_ts is not None:
|
|
433
|
+
treated_pre = float(did_series.loc[did_series["_time"] < intervention_ts, "treated_actual"].mean())
|
|
434
|
+
control_pre = float(did_series.loc[did_series["_time"] < intervention_ts, "control_actual"].mean())
|
|
435
|
+
did_series["treated_counterfactual"] = np.where(
|
|
436
|
+
did_series["_time"] >= intervention_ts,
|
|
437
|
+
treated_pre + did_series["control_actual"] - control_pre,
|
|
438
|
+
np.nan,
|
|
439
|
+
)
|
|
440
|
+
else:
|
|
441
|
+
did_series["treated_counterfactual"] = np.nan
|
|
442
|
+
did_series = did_series.rename(columns={"_time": time_col})
|
|
423
443
|
return MethodResult(
|
|
424
444
|
method=label,
|
|
425
445
|
summary=summary_df,
|
|
@@ -428,6 +448,14 @@ def fit_did_regression(
|
|
|
428
448
|
"analysis_frame": work_df,
|
|
429
449
|
"mde_power_curve": mde["power_curve"],
|
|
430
450
|
},
|
|
451
|
+
figures={
|
|
452
|
+
"did_effect": plot_did_effect(
|
|
453
|
+
did_series,
|
|
454
|
+
time_col=time_col,
|
|
455
|
+
intervention_time=intervention_ts,
|
|
456
|
+
title=f"{label} | {outcome_col}",
|
|
457
|
+
)
|
|
458
|
+
},
|
|
431
459
|
metadata={
|
|
432
460
|
"fit": fit,
|
|
433
461
|
"mde_mode": mde_mode,
|
|
@@ -827,6 +855,8 @@ def _did_placebo_fpr(
|
|
|
827
855
|
) -> tuple[int, int]:
|
|
828
856
|
pre_df = work_df.loc[work_df[time_col] < intervention_time].copy()
|
|
829
857
|
dates = sorted(pre_df[time_col].drop_duplicates())
|
|
858
|
+
if not dates or placebo_count <= 0:
|
|
859
|
+
return 0, 0
|
|
830
860
|
placebo_dates = [date for date in dates if date >= dates[0] + pd.Timedelta(days=28)]
|
|
831
861
|
if placebo_dates:
|
|
832
862
|
indexes = np.linspace(0, len(placebo_dates) - 1, min(placebo_count, len(placebo_dates)), dtype=int)
|
|
@@ -849,6 +879,7 @@ def _did_placebo_fpr(
|
|
|
849
879
|
mde_mode="none",
|
|
850
880
|
)
|
|
851
881
|
pvalues.append(float(result.summary.iloc[0]["p_value"]))
|
|
882
|
+
close_method_result_figures(result)
|
|
852
883
|
except Exception:
|
|
853
884
|
continue
|
|
854
885
|
return len(pvalues), int(sum(p < alpha for p in pvalues))
|
|
@@ -208,6 +208,8 @@ def _its_placebo_fpr(
|
|
|
208
208
|
) -> tuple[int, int]:
|
|
209
209
|
pre_df = work_df.loc[work_df[time_col] < intervention_time].copy()
|
|
210
210
|
dates = sorted(pre_df[time_col].drop_duplicates())
|
|
211
|
+
if not dates or placebo_count <= 0:
|
|
212
|
+
return 0, 0
|
|
211
213
|
placebo_dates = [
|
|
212
214
|
date for date in dates
|
|
213
215
|
if date >= dates[0] + pd.Timedelta(days=42)
|
|
@@ -230,6 +232,7 @@ def _its_placebo_fpr(
|
|
|
230
232
|
)
|
|
231
233
|
coefficients = result.details["coefficients"]
|
|
232
234
|
level = coefficients.loc[coefficients["term"] == "post_flag", "p_value"]
|
|
235
|
+
close_method_result_figures(result)
|
|
233
236
|
if level.empty:
|
|
234
237
|
continue
|
|
235
238
|
runs += 1
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/visualization.py
RENAMED
|
@@ -95,6 +95,34 @@ def plot_actual_vs_counterfactual(
|
|
|
95
95
|
return fig
|
|
96
96
|
|
|
97
97
|
|
|
98
|
+
def plot_did_effect(
|
|
99
|
+
series_df: pd.DataFrame,
|
|
100
|
+
time_col: str,
|
|
101
|
+
treated_actual_col: str = "treated_actual",
|
|
102
|
+
control_actual_col: str = "control_actual",
|
|
103
|
+
treated_counterfactual_col: str = "treated_counterfactual",
|
|
104
|
+
intervention_time: str | pd.Timestamp | None = None,
|
|
105
|
+
title: str = "DiD effect",
|
|
106
|
+
):
|
|
107
|
+
"""Plot DiD group means, treated counterfactual, and post-period gap."""
|
|
108
|
+
plot_df = series_df.sort_values(time_col).copy()
|
|
109
|
+
fig, ax = plt.subplots(1, 1, figsize=(12, 4))
|
|
110
|
+
ax.plot(plot_df[time_col], plot_df[treated_actual_col], label="treated actual", linewidth=2)
|
|
111
|
+
ax.plot(plot_df[time_col], plot_df[control_actual_col], label="control actual", linewidth=2)
|
|
112
|
+
post_mask = plot_df[treated_counterfactual_col].notna()
|
|
113
|
+
ax.plot(plot_df.loc[post_mask, time_col], plot_df.loc[post_mask, treated_counterfactual_col], label="treated counterfactual", linestyle="--", linewidth=2)
|
|
114
|
+
ax.fill_between(plot_df.loc[post_mask, time_col], plot_df.loc[post_mask, treated_actual_col], plot_df.loc[post_mask, treated_counterfactual_col], alpha=0.2, label="DiD effect")
|
|
115
|
+
if intervention_time is not None:
|
|
116
|
+
ax.axvline(pd.Timestamp(intervention_time), color="black", linestyle="--", linewidth=1)
|
|
117
|
+
ax.set_title(title)
|
|
118
|
+
ax.set_xlabel(time_col)
|
|
119
|
+
ax.set_ylabel("outcome")
|
|
120
|
+
ax.grid(alpha=0.25)
|
|
121
|
+
ax.legend()
|
|
122
|
+
plt.tight_layout()
|
|
123
|
+
return fig
|
|
124
|
+
|
|
125
|
+
|
|
98
126
|
def plot_gap_series(
|
|
99
127
|
gap_df: pd.DataFrame,
|
|
100
128
|
time_col: str,
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4/post_analysis_toolkit.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: post-analysis-toolkit
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Reusable helpers for post-analysis, quasi-causal designs, and diagnostics.
|
|
5
5
|
Author: OpenAI Codex
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -1151,4 +1151,4 @@ its_result = fit_its(
|
|
|
1151
1151
|
|
|
1152
1152
|
## Версия
|
|
1153
1153
|
|
|
1154
|
-
Текущая версия пакета: `1.0.
|
|
1154
|
+
Текущая версия пакета: `1.0.4`
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "post-analysis-toolkit"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.4"
|
|
8
8
|
description = "Reusable helpers for post-analysis, quasi-causal designs, and diagnostics."
|
|
9
9
|
readme = "post_analysis_toolkit/README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
File without changes
|
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/MDE_METHODOLOGY.md
RENAMED
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/REFERENCE.html
RENAMED
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/REFERENCE.md
RENAMED
|
File without changes
|
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/contracts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/mde_resampling.py
RENAMED
|
File without changes
|
{post_analysis_toolkit-1.0.2 → post_analysis_toolkit-1.0.4}/post_analysis_toolkit/observational.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|