Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add P75 quantile for Core Web Vitals - and globally #27409

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/lib/components/InsightLabel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function MathTag({ math, mathProperty, mathHogQL, mathGroupTypeIndex }: MathTagP
if (math === 'unique_group' && mathGroupTypeIndex != undefined) {
return <LemonTag>Unique {aggregationLabel(mathGroupTypeIndex).plural}</LemonTag>
}
if (math && ['sum', 'avg', 'min', 'max', 'median', 'p90', 'p95', 'p99'].includes(math || '')) {
if (math && ['sum', 'avg', 'min', 'max', 'median', 'p75', 'p90', 'p95', 'p99'].includes(math)) {
return (
<>
<LemonTag>{mathDefinitions[math]?.name || capitalizeFirstLetter(math)}</LemonTag>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3906,6 +3906,7 @@
"min_count_per_actor",
"max_count_per_actor",
"median_count_per_actor",
"p75_count_per_actor",
"p90_count_per_actor",
"p95_count_per_actor",
"p99_count_per_actor"
Expand Down Expand Up @@ -9099,7 +9100,7 @@
"type": "object"
},
"PropertyMathType": {
"enum": ["avg", "sum", "min", "max", "median", "p90", "p95", "p99"],
"enum": ["avg", "sum", "min", "max", "median", "p75", "p90", "p95", "p99"],
"type": "string"
},
"PropertyOperator": {
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/scenes/cohorts/CohortFilters/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export const FIELD_VALUES: Record<FieldOptionsType, FieldValues> = {
[PropertyMathType.Median]: {
label: 'Median',
},
[PropertyMathType.P75]: {
label: '75th percentile',
},
[PropertyMathType.P90]: {
label: '90th percentile',
},
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/scenes/trends/mathsLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,19 @@ export const PROPERTY_MATH_DEFINITIONS: Record<PropertyMathType, MathDefinition>
),
category: MathCategory.PropertyValue,
},
[PropertyMathType.P75]: {
name: '75th percentile',
shortName: '75th percentile',
description: (
<>
Event property 75th percentile.
<br />
<br />
For example 100 events captured with property <code>amount</code> equal to 101..200, result in 175.
</>
),
category: MathCategory.PropertyValue,
},
[PropertyMathType.P90]: {
name: '90th percentile',
shortName: '90th percentile',
Expand Down Expand Up @@ -315,6 +328,12 @@ export const COUNT_PER_ACTOR_MATH_DEFINITIONS: Record<CountPerActorMathType, Mat
description: <>Event count per actor 50th percentile.</>,
category: MathCategory.EventCountPerActor,
},
[CountPerActorMathType.P75]: {
name: '75th percentile',
shortName: '75th percentile',
description: <>Event count per actor 75th percentile.</>,
category: MathCategory.EventCountPerActor,
},
[CountPerActorMathType.P90]: {
name: '90th percentile',
shortName: '90th percentile',
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3651,6 +3651,7 @@ export enum PropertyMathType {
Minimum = 'min',
Maximum = 'max',
Median = 'median',
P75 = 'p75',
P90 = 'p90',
P95 = 'p95',
P99 = 'p99',
Expand All @@ -3661,6 +3662,7 @@ export enum CountPerActorMathType {
Minimum = 'min_count_per_actor',
Maximum = 'max_count_per_actor',
Median = 'median_count_per_actor',
P75 = 'p75_count_per_actor',
P90 = 'p90_count_per_actor',
P95 = 'p95_count_per_actor',
P99 = 'p99_count_per_actor',
Expand Down
1 change: 1 addition & 0 deletions posthog/api/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class PersonPropertiesSerializer(serializers.Serializer):
- `min`: min of a numeric property.
- `max`: max of a numeric property.
- `median`: median of a numeric property.
- `p75`: 75th percentile of a numeric property.
- `p90`: 90th percentile of a numeric property.
- `p95` 95th percentile of a numeric property.
- `p99`: 99th percentile of a numeric property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def select_aggregation(self) -> ast.Expr:
return self._math_func("max", None)
elif self.series.math == "median":
return self._math_quantile(0.5, None)
elif self.series.math == "p75":
return self._math_quantile(0.75, None)
elif self.series.math == "p90":
return self._math_quantile(0.9, None)
elif self.series.math == "p95":
Expand Down Expand Up @@ -106,6 +108,7 @@ def is_count_per_actor_variant(self):
"min_count_per_actor",
"max_count_per_actor",
"median_count_per_actor",
"p75_count_per_actor",
"p90_count_per_actor",
"p95_count_per_actor",
"p99_count_per_actor",
Expand Down Expand Up @@ -247,6 +250,8 @@ def _actors_inner_select_query(
math_func = self._math_func("max", ["total"])
elif self.series.math == "median_count_per_actor":
math_func = self._math_quantile(0.5, ["total"])
elif self.series.math == "p75_count_per_actor":
math_func = self._math_quantile(0.75, ["total"])
elif self.series.math == "p90_count_per_actor":
math_func = self._math_quantile(0.9, ["total"])
elif self.series.math == "p95_count_per_actor":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
[PropertyMathType.MIN, "$browser"],
[PropertyMathType.MAX, "$browser"],
[PropertyMathType.MEDIAN, "$browser"],
[PropertyMathType.P75, "$browser"],
[PropertyMathType.P90, "$browser"],
[PropertyMathType.P95, "$browser"],
[PropertyMathType.P99, "$browser"],
[CountPerActorMathType.AVG_COUNT_PER_ACTOR, None],
[CountPerActorMathType.MIN_COUNT_PER_ACTOR, None],
[CountPerActorMathType.MAX_COUNT_PER_ACTOR, None],
[CountPerActorMathType.MEDIAN_COUNT_PER_ACTOR, None],
[CountPerActorMathType.P75_COUNT_PER_ACTOR, None],
[CountPerActorMathType.P90_COUNT_PER_ACTOR, None],
[CountPerActorMathType.P95_COUNT_PER_ACTOR, None],
[CountPerActorMathType.P99_COUNT_PER_ACTOR, None],
Expand Down Expand Up @@ -79,13 +81,15 @@ def test_all_cases_return(
[PropertyMathType.MIN, False],
[PropertyMathType.MAX, False],
[PropertyMathType.MEDIAN, False],
[PropertyMathType.P75, False],
[PropertyMathType.P90, False],
[PropertyMathType.P95, False],
[PropertyMathType.P99, False],
[CountPerActorMathType.AVG_COUNT_PER_ACTOR, True],
[CountPerActorMathType.MIN_COUNT_PER_ACTOR, True],
[CountPerActorMathType.MAX_COUNT_PER_ACTOR, True],
[CountPerActorMathType.MEDIAN_COUNT_PER_ACTOR, True],
[CountPerActorMathType.P75_COUNT_PER_ACTOR, True],
[CountPerActorMathType.P90_COUNT_PER_ACTOR, True],
[CountPerActorMathType.P95_COUNT_PER_ACTOR, True],
[CountPerActorMathType.P99_COUNT_PER_ACTOR, True],
Expand Down
4 changes: 4 additions & 0 deletions posthog/hogql_queries/insights/trends/test/test_trends.py
Original file line number Diff line number Diff line change
Expand Up @@ -4094,6 +4094,10 @@ def test_max_filtering(self):
def test_median_filtering(self):
self._test_math_property_aggregation("median", values=range(101, 201), expected_value=150)

@also_test_with_materialized_columns(["some_number"])
def test_p75_filtering(self):
self._test_math_property_aggregation("p75", values=range(101, 201), expected_value=175)

@also_test_with_materialized_columns(["some_number"])
def test_p90_filtering(self):
self._test_math_property_aggregation("p90", values=range(101, 201), expected_value=190)
Expand Down
4 changes: 2 additions & 2 deletions posthog/management/commands/compare_hogql_insights.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ def handle(self, *args, **options):
# len(insights)
for insight in insights[0:500]:
for event in insight.filters.get("events", []):
if event.get("math") in ("median", "p90", "p95", "p99"):
if event.get("math") in ("median", "p75", "p90", "p95", "p99"):
event["math"] = "sum"
for event in insight.filters.get("actions", []):
if event.get("math") in ("median", "p90", "p95", "p99"):
if event.get("math") in ("median", "p75", "p90", "p95", "p99"):
event["math"] = "sum"
try:
print( # noqa: T201
Expand Down
8 changes: 5 additions & 3 deletions posthog/models/entity/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,26 @@
"monthly_active",
"unique_group",
"unique_session",
# TODO: When we are finally on Python 3.11+, inline the below as *PROPERTY_MATH_FUNCTIONS.keys()
"hogql",
# Equivalent to *PROPERTY_MATH_FUNCTIONS.keys(),
"sum",
"min",
"max",
"avg",
"median",
"p75",
"p90",
"p95",
"p99",
# TODO: When we are finally on Python 3.11+, inline the below as *COUNT_PER_ACTOR_MATH_FUNCTIONS.keys()
# Equivalent to *COUNT_PER_ACTOR_MATH_FUNCTIONS.keys()
"min_count_per_actor",
"max_count_per_actor",
"avg_count_per_actor",
"median_count_per_actor",
"p75_count_per_actor",
"p90_count_per_actor",
"p95_count_per_actor",
"p99_count_per_actor",
"hogql",
]


Expand Down
4 changes: 4 additions & 0 deletions posthog/queries/test/test_trends.py
Original file line number Diff line number Diff line change
Expand Up @@ -3611,6 +3611,10 @@ def test_max_filtering(self):
def test_median_filtering(self):
self._test_math_property_aggregation("median", values=range(101, 201), expected_value=150)

@also_test_with_materialized_columns(["some_number"])
def test_p75_filtering(self):
self._test_math_property_aggregation("p75", values=range(101, 201), expected_value=175)

@also_test_with_materialized_columns(["some_number"])
def test_p90_filtering(self):
self._test_math_property_aggregation("p90", values=range(101, 201), expected_value=190)
Expand Down
2 changes: 2 additions & 0 deletions posthog/queries/trends/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"min": "min",
"max": "max",
"median": "quantile(0.50)",
"p75": "quantile(0.75)",
"p90": "quantile(0.90)",
"p95": "quantile(0.95)",
"p99": "quantile(0.99)",
Expand All @@ -43,6 +44,7 @@
"min_count_per_actor": "min",
"max_count_per_actor": "max",
"median_count_per_actor": "quantile(0.50)",
"p75_count_per_actor": "quantile(0.75)",
"p90_count_per_actor": "quantile(0.90)",
"p95_count_per_actor": "quantile(0.95)",
"p99_count_per_actor": "quantile(0.99)",
Expand Down
2 changes: 2 additions & 0 deletions posthog/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ class CountPerActorMathType(StrEnum):
MIN_COUNT_PER_ACTOR = "min_count_per_actor"
MAX_COUNT_PER_ACTOR = "max_count_per_actor"
MEDIAN_COUNT_PER_ACTOR = "median_count_per_actor"
P75_COUNT_PER_ACTOR = "p75_count_per_actor"
P90_COUNT_PER_ACTOR = "p90_count_per_actor"
P95_COUNT_PER_ACTOR = "p95_count_per_actor"
P99_COUNT_PER_ACTOR = "p99_count_per_actor"
Expand Down Expand Up @@ -1290,6 +1291,7 @@ class PropertyMathType(StrEnum):
MIN = "min"
MAX = "max"
MEDIAN = "median"
P75 = "p75"
P90 = "p90"
P95 = "p95"
P99 = "p99"
Expand Down
Loading