Query dataframes with GitHub search syntax
Project description
Frame Search
A GitHub search inspired interface to DataFrames.
Powered by narwhals.
Installation
Install from PyPI:
uv add frame-search
Usage
API
Importing frame_search adds a search properties to pandas and polars objects.
# Import to add `search` property to DataFrames
import frame_search # noqa: F401
import polars as pl
df = pl.DataFrame({
"name": ["Alice Smith", "Bob J. Dawkins", "Charlie Brown"],
"age": [25, 30, 35],
"hometown": ["New York", "New York", "Chicago"]
})
df.search('age:<30 hometown:"New York"')
shape: (1, 3)
┌─────────────┬─────┬──────────┐
│ name ┆ age ┆ hometown │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ str │
╞═════════════╪═════╪══════════╡
│ Alice Smith ┆ 25 ┆ New York │
└─────────────┴─────┴──────────┘
Interactive Search in Marimo Notebooks
Use with marimo to create a search interface for DataFrames:
import marimo as mo
search = mo.ui.text(label="DataFrame Search Query:")
search
Then use on a DataFrame:
import polars as pl
import frame_search # noqa: F401
df = pl.DataFrame({
"name": ["Alice Smith", "Bob J. Dawkins", "Charlie Brown"],
"age": [25, 30, 35],
"hometown": ["New York", "Los Angeles", "Chicago"]
})
df_filter = df.search(search.value)
df_filter
Here is another example in a Marimo notebook:
Features
| Syntax | Description | Example |
|---|---|---|
key:value |
Case-insensitive substring match | name:alice |
key:value1,value2 |
Match any of the values (isin) | hobby:Reading,Sports |
key:low..high |
Range match (inclusive) | age:20..40 |
key:>value |
Comparator (<, <=, >, >=, ==, !=) |
age:>30 |
"quoted value" |
Exact string with spaces | city:"New York" |
is:col |
Boolean column is True |
is:active |
has:col |
Column is not null | has:nickname |
no:col |
Column is null | no:nickname |
term1 term2 |
Implicit AND (space-separated) | name:alice age:>20 |
term1 AND term2 / term1 & term2 |
Explicit AND | name:alice AND age:>20 |
term1 OR term2 / term1 | term2 |
OR operator | hobby:Reading OR hobby:Sports |
NOT term / -term / ~term |
Negation | -name:alice, NOT age:>30 |
(expr) |
Grouping with parentheses | (name:alice OR name:bob) AND age:>20 |
`col name`:value |
Backtick-quoted column with spaces | `first name`:alice |
Search Expression Grammar
This repository defines a small, expressive query language for filtering and searching structured data. The grammar is implemented in Lark and supports boolean logic, comparisons, ranges, set membership, dates, numbers, strings, and quoted identifiers.
The language is designed to be:
- Readable for humans
- Unambiguous for the parser
- Flexible enough to express common filtering patterns
Syntax Overview
A query is an expression composed of:
- Boolean operators:
AND,OR,NOT(with symbolic aliases&,|,~) - Comparisons between a key and a value
- Range expressions (
..) - Set membership (
value,value,...) - Parentheses for grouping
At a high level:
<key> <comparator> <search_rhs>
Where a key identifies the field being queried. A comparator represents an operator that compares two sides (e.g. <, >, ==). search_rhs can take on many different values including dates/datetimes, integers/floats, booleans, strings, and other columns.
Keys
Keys identify the field being queried, and are always inferred to exist on the left side of any comparison. To refer to column names that have spaces in them, one needs to surround the name in backticks.
name:Alice # queries the name column for the string Alice
`first name`:Alice # queries the `first name` column for the string Alice
`first.name`:Alice # queries the `first.name` column for the string Alice
In the above example, both "first name" and "first.name" must be surrounded in backticks.
Comparators
| Operator | Meaning |
|---|---|
== |
equality |
!= |
inequality |
< |
less than |
<= |
less than or equal |
> |
greater than |
>= |
greater than or equal |
: |
value dependent |
The : operator is special in that it allows for a flexible supset of expressions to be parsed and used
str:name:Alicequeries the name column for any value that starts with Alice or alice (case-insensitive prefix matching)isin:name:Alice,Bobqueries the name column for either Alice or Bob (same as case-insensitive prefix matching for strings)range:age:20..40queries the age column for any value between 20 and 40 (inclusive)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file frame_search-0.4.0.tar.gz.
File metadata
- Download URL: frame_search-0.4.0.tar.gz
- Upload date:
- Size: 201.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
380e1ba1f347d8fe396a64e212c3d3867d4bfafad079f97243ff8805b00e7afc
|
|
| MD5 |
f3bdf3c936b09ef6de3dc44908df76e4
|
|
| BLAKE2b-256 |
5ef6a95c3f70b6a91504025f9c304894a902b308a3e3954948866a823472d43a
|
File details
Details for the file frame_search-0.4.0-py3-none-any.whl.
File metadata
- Download URL: frame_search-0.4.0-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1cdfc3b246d0556a47a650439da9021f0d3b99892387374d7c5d78c4a7d9d6b7
|
|
| MD5 |
c307e55719a58c1be17f72930408518c
|
|
| BLAKE2b-256 |
fdf593dc3a7dfbd59b6fe2a260e2f257d9c0861f7985122d0136ce9ae9f97930
|