{
  "slug": "iqr-outlier-trimmer",
  "name": "gizza-ai/iqr-outlier-trimmer",
  "version": "0.1.0",
  "title": "IQR Outlier Trimmer — Remove Outlier Rows from CSV (Tukey Fences) — gizza.ai",
  "description": "Drop the CSV rows outside Q1-k*IQR to Q3+k*IQR on a column you choose. Adjustable k, winsorize or flag instead, quartile stats. Free, in-browser, no upload.",
  "tags": [
    "iqr outlier",
    "tukey fences",
    "remove outliers csv",
    "outlier removal",
    "winsorize"
  ],
  "category": "math",
  "urls": {
    "page": "https://gizza.ai/tools/iqr-outlier-trimmer/",
    "markdown": "https://gizza.ai/tools/iqr-outlier-trimmer/index.md",
    "descriptor": "https://gizza.ai/tools/iqr-outlier-trimmer/tool.json",
    "deep_link_example": "https://gizza.ai/tools/iqr-outlier-trimmer/?data=name%2Cprice%0Aa%2C10%0Ab%2C11%0Ac%2C12%0Ad%2C13%0Ae%2C100&columns=price&k=1.5&action=remove&output=csv&header=true&delimiter=comma&quartile_method=linear&match_mode=any&non_numeric=keep"
  },
  "cli": "gizza tool iqr-outlier-trimmer \"name,price\na,10\nb,11\nc,12\nd,13\ne,100\"",
  "tool": {
    "description": "Drop the outlier rows of a CSV/TSV table using Tukey's fences: for each analysed column, compute Q1, Q3 and IQR = Q3 - Q1, then treat a cell below Q1 - k*IQR or above Q3 + k*IQR as an outlier (k defaults to 1.5). Choose the columns by header name or 1-based index (blank = every numeric column), and choose what happens to the flagged rows: remove them, keep only them, clip (winsorize) the offending cells to their fence, or flag them with an extra column. output='report' returns the quartiles, fences and outlier counts instead of the table. Quartiles support the linear (numpy/pandas), exclusive (Moore & McCabe / TI-83) and inclusive (Tukey's hinges) conventions. The header row is preserved, blank/non-numeric cells never enter the quartile maths, and the delimiter of the input is used for the output.",
    "parameters": {
      "additionalProperties": false,
      "properties": {
        "action": {
          "default": "remove",
          "description": "What to do with the outlier rows: 'remove' drops them (default), 'keep' returns ONLY them, 'clip' winsorizes — clamps each out-of-fence cell to its fence and keeps every row, 'flag' appends an 'outlier' column of true/false and drops nothing.",
          "enum": [
            "remove",
            "keep",
            "clip",
            "flag"
          ],
          "type": "string"
        },
        "columns": {
          "description": "Comma-separated columns to fence — header names (needs a header) or 1-based indexes, e.g. 'price' or '2,3'. Blank analyses every numeric column.",
          "type": "string"
        },
        "data": {
          "description": "The CSV/TSV text to trim, including the header row when header=true.",
          "type": "string"
        },
        "delimiter": {
          "default": "comma",
          "description": "Field separator of the input (and of the output): 'comma', 'tab', 'semicolon', or 'pipe'. Default 'comma'.",
          "enum": [
            "comma",
            "tab",
            "semicolon",
            "pipe"
          ],
          "type": "string"
        },
        "header": {
          "default": true,
          "description": "Treat the first row as a header: keep it verbatim, never fence-test it, and let 'columns' use its names. Default true.",
          "type": "boolean"
        },
        "k": {
          "default": 1.5,
          "description": "Tukey fence multiplier: a row is an outlier when the cell is below Q1 - k*IQR or above Q3 + k*IQR. 1.5 = the classic mild fence (default), 3 = extreme outliers only; 0 fences at the quartiles themselves.",
          "maximum": 5,
          "minimum": 0,
          "type": "number"
        },
        "match_mode": {
          "default": "any",
          "description": "With several analysed columns, is a row an outlier when 'any' column is out of fence (default) or only when 'all' of them are?",
          "enum": [
            "any",
            "all"
          ],
          "type": "string"
        },
        "non_numeric": {
          "default": "keep",
          "description": "How to treat a blank or non-numeric cell in an analysed column: 'keep' counts it as in-fence (default), 'remove' counts it as an outlier so action=remove drops that row too. Either way such cells are excluded from the quartile maths.",
          "enum": [
            "keep",
            "remove"
          ],
          "type": "string"
        },
        "output": {
          "default": "csv",
          "description": "'csv' returns the resulting table (default); 'report' returns the per-column Q1/Q3/IQR, both fences, and the outlier/kept row counts and percentages instead.",
          "enum": [
            "csv",
            "report"
          ],
          "type": "string"
        },
        "quartile_method": {
          "default": "linear",
          "description": "Quartile convention: 'linear' interpolates between order statistics (numpy/pandas default, Excel QUARTILE.INC) — the default; 'exclusive' is Moore & McCabe / TI-83 (the median is excluded from both halves when the count is odd); 'inclusive' is Tukey's hinges (the median belongs to both halves).",
          "enum": [
            "linear",
            "exclusive",
            "inclusive"
          ],
          "type": "string"
        }
      },
      "required": [
        "data"
      ],
      "type": "object"
    }
  }
}