fuzzybunny 0.1.2__cp38-cp38-win32.whl → 0.2.1__cp38-cp38-win32.whl

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.
fuzzybunny/__init__.py ADDED
@@ -0,0 +1,75 @@
1
+ from . import _fuzzybunny
2
+ from ._fuzzybunny import (
3
+ levenshtein,
4
+ jaccard,
5
+ token_sort,
6
+ partial_ratio,
7
+ )
8
+
9
+ from .benchmark import benchmark, benchmark_batch
10
+
11
+ def rank(query, candidates, scorer="levenshtein", mode="full", process=True, threshold=0.0, top_n=-1, weights=None):
12
+ """
13
+ Enhanced rank function with support for Pandas Series and NumPy arrays.
14
+ """
15
+ if weights is None:
16
+ weights = {}
17
+
18
+ # Check for pandas/numpy
19
+ if _is_pandas_series(candidates):
20
+ candidates = candidates.astype(str).tolist()
21
+ elif _is_numpy_array(candidates):
22
+ candidates = candidates.astype(str).tolist()
23
+
24
+ return _fuzzybunny.rank(query, candidates, scorer, mode, process, threshold, top_n, weights)
25
+
26
+ def batch_match(queries, candidates, scorer="levenshtein", mode="full", process=True, threshold=0.0, top_n=-1, weights=None):
27
+ """
28
+ Enhanced batch_match function with support for Pandas/NumPy candidates.
29
+ """
30
+ if weights is None:
31
+ weights = {}
32
+
33
+ if _is_pandas_series(candidates):
34
+ candidates = candidates.astype(str).tolist()
35
+ elif _is_numpy_array(candidates):
36
+ candidates = candidates.astype(str).tolist()
37
+
38
+ # queries can also be pandas/numpy
39
+ if _is_pandas_series(queries) or _is_numpy_array(queries):
40
+ import numpy as np
41
+ queries = np.array(queries).astype(str).tolist()
42
+
43
+ return _fuzzybunny.batch_match(queries, candidates, scorer, mode, process, threshold, top_n, weights)
44
+
45
+ def _is_pandas_series(obj):
46
+ try:
47
+ import pandas as pd
48
+ return isinstance(obj, pd.Series)
49
+ except ImportError:
50
+ return False
51
+
52
+ def _is_numpy_array(obj):
53
+ try:
54
+ import numpy as np
55
+ return isinstance(obj, np.ndarray)
56
+ except ImportError:
57
+ return False
58
+
59
+ def _register_pandas_accessor():
60
+ try:
61
+ import pandas as pd
62
+
63
+ @pd.api.extensions.register_series_accessor("fuzzy")
64
+ class FuzzyAccessor:
65
+ def __init__(self, pandas_obj):
66
+ self._obj = pandas_obj
67
+
68
+ def match(self, query, scorer="levenshtein", mode="full", process=True, threshold=0.0, top_n=-1, weights=None):
69
+ return rank(query, self._obj, scorer, mode, process, threshold, top_n, weights)
70
+ except (ImportError, AttributeError):
71
+ pass
72
+
73
+ _register_pandas_accessor()
74
+
75
+ __version__ = getattr(_fuzzybunny, "__version__", "dev")
Binary file
@@ -0,0 +1,49 @@
1
+ import time
2
+ import statistics
3
+
4
+ def benchmark(query, candidates, scorers=None, n_runs=5):
5
+ """
6
+ Benchmark different scorers on a given query and set of candidates.
7
+ Returns a dictionary with timing results.
8
+ """
9
+ from . import rank
10
+ if scorers is None:
11
+ scorers = ["levenshtein", "jaccard", "token_sort"]
12
+
13
+ results = {}
14
+
15
+ for scorer in scorers:
16
+ times = []
17
+ for _ in range(n_runs):
18
+ start = time.perf_counter()
19
+ rank(query, candidates, scorer=scorer)
20
+ end = time.perf_counter()
21
+ times.append(end - start)
22
+
23
+ results[scorer] = {
24
+ "mean": statistics.mean(times),
25
+ "stddev": statistics.stdev(times) if len(times) > 1 else 0,
26
+ "min": min(times),
27
+ "max": max(times)
28
+ }
29
+
30
+ return results
31
+
32
+ def benchmark_batch(queries, candidates, scorer="levenshtein", n_runs=3):
33
+ """
34
+ Benchmark batch_match performance.
35
+ """
36
+ from . import batch_match
37
+ times = []
38
+ for _ in range(n_runs):
39
+ start = time.perf_counter()
40
+ batch_match(queries, candidates, scorer=scorer)
41
+ end = time.perf_counter()
42
+ times.append(end - start)
43
+
44
+ return {
45
+ "mean": statistics.mean(times),
46
+ "total_queries": len(queries),
47
+ "total_candidates": len(candidates),
48
+ "queries_per_second": len(queries) / statistics.mean(times)
49
+ }
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.1
2
+ Name: fuzzybunny
3
+ Version: 0.2.1
4
+ Summary: A fuzzy search tool for python written in C++
5
+ Home-page: https://github.com/cachevector/fuzzybunny
6
+ Project-URL: Bug Tracker, https://github.com/cachevector/fuzzybunny/issues
7
+ Project-URL: Source Code, https://github.com/cachevector/fuzzybunny
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+
12
+ <p align="center">
13
+ <img src="https://raw.githubusercontent.com/cachevector/fuzzybunny/master/docs/assets/fuzzybunny.png" alt="FuzzyBunny Logo" width="150" />
14
+ </p>
15
+
16
+ <h1 align="center">FuzzyBunny</h1>
17
+
18
+ <p align="center">
19
+ <b> A high-performance, lightweight Python library for fuzzy string matching and ranking, implemented in C++ with Pybind11. </b>
20
+ </p>
21
+
22
+ <p align="center">
23
+ <img src="https://img.shields.io/badge/License-MIT-green" />
24
+ <img src="https://img.shields.io/badge/Language-C%2B%2B-00599C" />
25
+ <img src="https://img.shields.io/badge/Bindings-Pybind11-blue" />
26
+ </p>
27
+
28
+ ## Features
29
+
30
+ - **Blazing Fast**: C++ core for 2-5x speed improvement over pure Python alternatives.
31
+ - **Multiple Scorers**: Support for Levenshtein, Jaccard, and Token Sort ratios.
32
+ - **Partial Matching**: Find the best substring matches.
33
+ - **Hybrid Scoring**: Combine multiple scorers with custom weights.
34
+ - **Pandas & NumPy Integration**: Native support for Series and Arrays.
35
+ - **Batch Processing**: Parallelized matching for large datasets using OpenMP.
36
+ - **Unicode Support**: Handles international characters and normalization.
37
+ - **Benchmarking Tools**: Built-in utilities to measure performance.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install fuzzybunny
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ ```python
48
+ import fuzzybunny
49
+
50
+ # Basic matching
51
+ score = fuzzybunny.levenshtein("kitten", "sitting")
52
+ print(f"Similarity: {score:.2f}")
53
+
54
+ # Ranking candidates
55
+ candidates = ["apple", "apricot", "banana", "cherry"]
56
+ results = fuzzybunny.rank("app", candidates, top_n=2)
57
+ # [('apple', 0.6), ('apricot', 0.42)]
58
+ ```
59
+
60
+ ## Advanced Usage
61
+
62
+ ### Hybrid Scorer
63
+ Combine different algorithms to get better results:
64
+
65
+ ```python
66
+ results = fuzzybunny.rank(
67
+ "apple banana",
68
+ ["banana apple"],
69
+ scorer="hybrid",
70
+ weights={"levenshtein": 0.3, "token_sort": 0.7}
71
+ )
72
+ ```
73
+
74
+ ### Pandas Integration
75
+ Use the specialized accessor for clean code:
76
+
77
+ ```python
78
+ import pandas as pd
79
+ import fuzzybunny
80
+
81
+ df = pd.DataFrame({"names": ["apple pie", "banana bread", "cherry tart"]})
82
+ results = df["names"].fuzzy.match("apple", mode="partial")
83
+ ```
84
+
85
+ ### Benchmarking
86
+ Compare performance on your specific data:
87
+
88
+ ```python
89
+ perf = fuzzybunny.benchmark("query", candidates)
90
+ print(f"Levenshtein mean time: {perf['levenshtein']['mean']:.6f}s")
91
+ ```
92
+
93
+ ## License
94
+ MIT
@@ -0,0 +1,8 @@
1
+ fuzzybunny/__init__.py,sha256=P2QxF06r8iOSnRKnLiJ0Uq2HBm7BoFthZ7rWGs252k0,2470
2
+ fuzzybunny/_fuzzybunny.cp38-win32.pyd,sha256=8toFjIPCbHP5Zbmjdr8HQ7suxOMB4wrQ8aEQquCnmzs,160256
3
+ fuzzybunny/benchmark.py,sha256=Qmg4-CBnB3RXDBHBY4zI5648isWcmT99EbRcEeID9-4,1481
4
+ fuzzybunny-0.2.1.dist-info/LICENSE,sha256=hvCYI5G-uZ41pxcDhQFHZHyMLk6BxmI_a27L1656lpo,1093
5
+ fuzzybunny-0.2.1.dist-info/METADATA,sha256=LfcB0Ti8oJgYzLW3J40Sham7SlO_rr3XgCZt5P9wMag,2761
6
+ fuzzybunny-0.2.1.dist-info/WHEEL,sha256=eVYmGj5rXRtpsCfsI3rXVwEX_vwxTLMXmwf_caP9MfU,95
7
+ fuzzybunny-0.2.1.dist-info/top_level.txt,sha256=rBIGqLOrlMo_aY9-MDE05n-7FuenH7CnsVNydAlCa_E,11
8
+ fuzzybunny-0.2.1.dist-info/RECORD,,
@@ -1,109 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: fuzzybunny
3
- Version: 0.1.2
4
- Summary: A fuzzy search tool for python written in C++
5
- Requires-Python: >=3.8
6
- Description-Content-Type: text/markdown
7
- License-File: LICENSE
8
-
9
- <p align="center">
10
- <img src="./docs/assets/fuzzybunny.png" alt="FuzzyBunny Logo" width="150" />
11
- </p>
12
-
13
- <h1 align="center">FuzzyBunny</h1>
14
-
15
- <p align="center">
16
- <b> A fuzzy search tool written in C++ with Python bindings </b>
17
- </p>
18
-
19
- <p align="center">
20
- <img src="https://img.shields.io/badge/License-MIT-green" />
21
- <img src="https://img.shields.io/badge/Language-C%2B%2B-00599C" />
22
- <img src="https://img.shields.io/badge/Bindings-Pybind11-blue" />
23
- </p>
24
-
25
- ## Overview
26
-
27
- FuzzyBunny is a lightweight, high-performance Python library for fuzzy string matching and ranking. It is implemented in C++ for speed and exposes a Pythonic API via Pybind11. It supports various scoring algorithms including Levenshtein, Jaccard, and Token Sort, along with partial matching capabilities.
28
-
29
- ## Features
30
-
31
- - **Fast C++ Core**: Optimized string matching algorithms.
32
- - **Multiple Scorers**:
33
- - `levenshtein`: Standard edit distance ratio.
34
- - `jaccard`: Set-based similarity.
35
- - `token_sort`: Sorts tokens before comparing (good for "Apple Banana" vs "Banana Apple").
36
- - **Ranking**: Efficiently rank a list of candidates against a query.
37
- - **Partial Matching**: Support for substring matching via `mode='partial'`.
38
- - **Unicode Support**: Correctly handles UTF-8 input.
39
-
40
- ## Installation
41
-
42
- ### Prerequisites
43
- - Python 3.8+
44
- - C++17 compatible compiler (GCC, Clang, MSVC)
45
-
46
- ### Using uv (Recommended)
47
-
48
- ```bash
49
- uv pip install .
50
- ```
51
-
52
- ### Using pip
53
-
54
- ```bash
55
- pip install .
56
- ```
57
-
58
- ## Usage
59
-
60
- ```python
61
- import fuzzybunny
62
-
63
- # Basic Levenshtein Ratio
64
- score = fuzzybunny.levenshtein("kitten", "sitting")
65
- print(f"Score: {score}") # ~0.57
66
-
67
- # Partial Matching
68
- # "apple" is a perfect substring of "apple pie"
69
- score = fuzzybunny.partial_ratio("apple", "apple pie")
70
- print(f"Partial Score: {score}") # 1.0
71
-
72
- # Ranking Candidates
73
- candidates = ["apple pie", "banana bread", "cherry tart", "apple crisp"]
74
- results = fuzzybunny.rank(
75
- query="apple",
76
- candidates=candidates,
77
- scorer="levenshtein",
78
- mode="partial",
79
- top_n=2
80
- )
81
-
82
- for candidate, score in results:
83
- print(f"{candidate}: {score}")
84
- # Output:
85
- # apple pie: 1.0
86
- # apple crisp: 1.0
87
- ```
88
-
89
- ## Development
90
-
91
- 1. **Setup Environment**:
92
- ```bash
93
- uv venv
94
- source .venv/bin/activate
95
- ```
96
-
97
- 2. **Install in Editable Mode**:
98
- ```bash
99
- uv pip install -e .
100
- ```
101
-
102
- 3. **Run Tests**:
103
- ```bash
104
- pytest
105
- ```
106
-
107
- ## License
108
-
109
- This project is licensed under the [MIT License](LICENSE).
@@ -1,6 +0,0 @@
1
- fuzzybunny.cp38-win32.pyd,sha256=VjZeyTOpl-sFgpJvwuydDzcXaU_FRbNSwW8rhXoA3oY,153088
2
- fuzzybunny-0.1.2.dist-info/LICENSE,sha256=hvCYI5G-uZ41pxcDhQFHZHyMLk6BxmI_a27L1656lpo,1093
3
- fuzzybunny-0.1.2.dist-info/METADATA,sha256=CNDl4Q4omhlHJ6NfX472wSiS3h6h9bTDOo1JTuIW4vQ,2714
4
- fuzzybunny-0.1.2.dist-info/WHEEL,sha256=eVYmGj5rXRtpsCfsI3rXVwEX_vwxTLMXmwf_caP9MfU,95
5
- fuzzybunny-0.1.2.dist-info/top_level.txt,sha256=rBIGqLOrlMo_aY9-MDE05n-7FuenH7CnsVNydAlCa_E,11
6
- fuzzybunny-0.1.2.dist-info/RECORD,,
fuzzybunny.cp38-win32.pyd DELETED
Binary file