# Exporting features when column value between specific percentiles

I want to do a statistical analysis. I need to export some features. Their column value between 10%-90% (or 20%-80%) percentile in order to avoid outliers' effect. I can't find a function in the expression window. There are q1, q3, median. They return 25%, 75% and 50% percentile values

There are related posts I found here. None of them meets my need.

How can I export features, their column value is between specific range like 10%-90%, 20%-80% etc?

You can create a new function which returns a percentile value, then, compare the field value.

1. Open `Select Feature by Expression` tool
2. Create new function in the Function Editor using the script below. (How to use the Function Editor)
``````from qgis.core import *
from qgis.gui import *
import numpy as np

values, layer = None, None
@qgsfunction(args='auto', group='Custom')
def percentile(per, layer_name, field_name, feature, parent):
global layer, values

if values is None:
layer = QgsProject.instance().mapLayersByName(layer_name)
values = [f[field_name] for f in layer.getFeatures()]

return float(np.percentile(values, per))
``````
1. Run this expression to select features whose field value is between 10%-90% percentile. You can change `10` and `90` to change the range.
``````percentile(10, @layer_name, 'FIELD') < FIELD < percentile(90, @layer_name, 'FIELD')
``````
• Note: The 3rd parameter (field name) in `percentile` function must be string -> `'FIELD'`. Please read this: Writing an expression
1. Use `Extract selected feature` tool.

You can use `Select by expression` and paste this expressions (see also screenshots below):

1. For the lowest 10%:
``````"value" <=
array_get(
array_sort (
array_agg ("value")
),
aggregate (
@layer,
'count',
"value"
) / 10 - 1
)
``````
1. For the highest 10%:
``````"value" >=
array_get(
array_sort (
array_agg ("value")
),
aggregate (
@layer,
'count',
"value"
) / 10*9
)
``````

Combine both expressions with `or` to the the lowest 10% plus the highest 10% (0-10%, 90-100%).

Screenshot: applying this to a layer with 100 points and an attribute field called `value` containing random values from 1 to 1000, it will select the lowest 10 (from 100) `values` entries: And for the highest values: And combined: 