ravenclaw 0.1.0__tar.gz

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.
Files changed (65) hide show
  1. ravenclaw-0.1.0/PKG-INFO +281 -0
  2. ravenclaw-0.1.0/README.md +255 -0
  3. ravenclaw-0.1.0/ravenclaw/__init__.py +23 -0
  4. ravenclaw-0.1.0/ravenclaw/clustering/__init__.py +5 -0
  5. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/__init__.py +7 -0
  6. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/auto_cluster.py +155 -0
  7. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/auto_kmeans.py +286 -0
  8. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/cluster.py +62 -0
  9. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/k_selection.py +96 -0
  10. ravenclaw-0.1.0/ravenclaw/clustering/kmeans/preprocessing.py +24 -0
  11. ravenclaw-0.1.0/ravenclaw/clustering/utils.py +77 -0
  12. ravenclaw-0.1.0/ravenclaw/preprocessing/__init__.py +29 -0
  13. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/__init__.py +24 -0
  14. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_date_to_day_of_week.py +80 -0
  15. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_date_to_day_of_year.py +78 -0
  16. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_datetime_to_day_of_year.py +78 -0
  17. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_datetime_to_hour_of_day.py +78 -0
  18. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_time_to_hour_of_day.py +83 -0
  19. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/convert_to_sin_cos.py +31 -0
  20. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/encode_day_of_week.py +107 -0
  21. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/encode_day_of_year.py +68 -0
  22. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/encode_hour_of_day.py +82 -0
  23. ravenclaw-0.1.0/ravenclaw/preprocessing/column_conversion/encode_one_hot.py +110 -0
  24. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/__init__.py +26 -0
  25. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/column_classifier.py +48 -0
  26. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/column_type_detectors.py +495 -0
  27. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_categorical_columns.py +54 -0
  28. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_date_columns.py +127 -0
  29. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_day_of_week_columns.py +121 -0
  30. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_float_columns.py +46 -0
  31. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_integer_columns.py +66 -0
  32. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_numeric_columns.py +46 -0
  33. ravenclaw-0.1.0/ravenclaw/preprocessing/column_detection/find_time_columns.py +81 -0
  34. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/__init__.py +25 -0
  35. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/base_encoder.py +58 -0
  36. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_date_to_day_of_week_converter.py +101 -0
  37. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_date_to_day_of_year_converter.py +116 -0
  38. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_datetime_converter.py +118 -0
  39. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_day_of_week_encoder.py +77 -0
  40. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_day_of_year_encoder.py +77 -0
  41. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_hour_of_day_encoder.py +116 -0
  42. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_non_numeric_encoder.py +158 -0
  43. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_one_hot_encoder.py +83 -0
  44. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_string_temporal_converter.py +267 -0
  45. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/df_time_to_hour_of_day_converter.py +99 -0
  46. ravenclaw-0.1.0/ravenclaw/preprocessing/df_encoders/feature_engineering_pipeline.py +255 -0
  47. ravenclaw-0.1.0/ravenclaw/preprocessing/encode_categorical_features.py +51 -0
  48. ravenclaw-0.1.0/ravenclaw/preprocessing/utils/__init__.py +27 -0
  49. ravenclaw-0.1.0/ravenclaw/preprocessing/utils/sample_size_calculators.py +100 -0
  50. ravenclaw-0.1.0/ravenclaw/preprocessing/utils/sampling_helper.py +131 -0
  51. ravenclaw-0.1.0/ravenclaw/preprocessing/utils/string_temporal_detector.py +299 -0
  52. ravenclaw-0.1.0/ravenclaw/preprocessing/utils/value_constraints.py +53 -0
  53. ravenclaw-0.1.0/ravenclaw/wrangling/__init__.py +37 -0
  54. ravenclaw-0.1.0/ravenclaw/wrangling/column_reordering.py +129 -0
  55. ravenclaw-0.1.0/ravenclaw/wrangling/join_wisely.py +164 -0
  56. ravenclaw-0.1.0/ravenclaw/wrangling/select_extreme.py +210 -0
  57. ravenclaw-0.1.0/ravenclaw/wrangling/split_rows.py +103 -0
  58. ravenclaw-0.1.0/ravenclaw/wrangling/standardize_columns.py +163 -0
  59. ravenclaw-0.1.0/ravenclaw.egg-info/PKG-INFO +281 -0
  60. ravenclaw-0.1.0/ravenclaw.egg-info/SOURCES.txt +63 -0
  61. ravenclaw-0.1.0/ravenclaw.egg-info/dependency_links.txt +1 -0
  62. ravenclaw-0.1.0/ravenclaw.egg-info/requires.txt +8 -0
  63. ravenclaw-0.1.0/ravenclaw.egg-info/top_level.txt +1 -0
  64. ravenclaw-0.1.0/setup.cfg +4 -0
  65. ravenclaw-0.1.0/setup.py +42 -0
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.1
2
+ Name: ravenclaw
3
+ Version: 0.1.0
4
+ Summary: Data wrangling and feature engineering toolkit for pandas DataFrames
5
+ Home-page: https://github.com/idin/ravenclaw
6
+ Author: Idin
7
+ Author-email: py@idin.net
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: pandas>=1.3.0
20
+ Requires-Dist: numpy>=1.20.0
21
+ Requires-Dist: scikit-learn>=1.0.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=6.0; extra == "dev"
24
+ Requires-Dist: black; extra == "dev"
25
+ Requires-Dist: flake8; extra == "dev"
26
+
27
+ # Ravenclaw - Intelligent Data Preprocessing and Clustering
28
+
29
+ A comprehensive toolkit for automated feature engineering and clustering with pandas DataFrames. Ravenclaw intelligently detects column types, converts temporal strings, creates cyclical encodings, and performs automatic clustering - all with minimal configuration.
30
+
31
+ ## 🎯 Key Features
32
+
33
+ ### **Intelligent Preprocessing Pipeline**
34
+ - **Automatic Detection**: Identifies datetime, date, time, and categorical columns in string format
35
+ - **Smart Conversion**: Converts string temporal data to proper types with format learning
36
+ - **Cyclical Encoding**: Creates sin/cos features for temporal data (perfect for ML models)
37
+ - **One-Hot Encoding**: Handles categorical variables with temporal safety checks
38
+ - **Sklearn Compatible**: Standard fit/transform interface for seamless integration
39
+
40
+ ### **Advanced Clustering**
41
+ - **AutoKMeans**: Automatically determines optimal number of clusters
42
+ - **Multiple Methods**: Silhouette, Calinski-Harabasz, Davies-Bouldin, and Elbow methods
43
+ - **Built-in Preprocessing**: Integrated scaling and imputation
44
+ - **Column Selection**: Flexible include/exclude functionality
45
+ - **Sklearn Interface**: Drop-in replacement for standard KMeans
46
+
47
+ ## 🚀 Quick Start
48
+
49
+ ### Installation
50
+
51
+ ```bash
52
+ pip install ravenclaw
53
+ ```
54
+
55
+ ### Complete ML Pipeline Example
56
+
57
+ Here's how to preprocess mixed data and cluster it in a single pipeline:
58
+
59
+ ```python
60
+ import pandas as pd
61
+ import numpy as np
62
+ from ravenclaw.preprocessing.df_encoders import FeatureEngineeringPipeline
63
+ from ravenclaw.clustering.kmeans import AutoKMeans
64
+ from sklearn.pipeline import Pipeline
65
+
66
+ # Create sample mixed data (the kind you get in real life!)
67
+ np.random.seed(42)
68
+ df = pd.DataFrame({
69
+ 'timestamp': ['2023-01-15 14:30:00', '2023-06-30 09:15:00', '2023-12-25 18:45:00'] * 50,
70
+ 'date_created': ['2023-01-15', '2023-06-30', '2023-12-25'] * 50,
71
+ 'time_of_day': ['14:30:00', '09:15:00', '18:45:00'] * 50,
72
+ 'category': ['Premium', 'Standard', 'Basic'] * 50,
73
+ 'region': ['North', 'South', 'East', 'West'] * 37 + ['North', 'South', 'East'],
74
+ 'revenue': np.random.normal(1000, 200, 150),
75
+ 'customer_age': np.random.randint(18, 80, 150),
76
+ 'satisfaction': np.random.uniform(1, 5, 150)
77
+ })
78
+
79
+ # Add some missing values (real data is messy!)
80
+ df.loc[np.random.choice(150, 10), 'revenue'] = np.nan
81
+ df.loc[np.random.choice(150, 5), 'satisfaction'] = np.nan
82
+
83
+ print(f"Original data: {df.shape[1]} columns")
84
+ print(f"Column types: {df.dtypes.value_counts().to_dict()}")
85
+
86
+ # Step 1: Feature Engineering Pipeline
87
+ # Automatically detects and converts temporal strings, creates cyclical features
88
+ preprocessor = FeatureEngineeringPipeline.create_default()
89
+ processed_df = preprocessor.fit_transform(df)
90
+
91
+ print(f"After preprocessing: {processed_df.shape[1]} columns")
92
+ print(f"New features: {list(processed_df.columns)}")
93
+
94
+ # Step 2: Automatic Clustering with Built-in Imputation
95
+ # AutoKMeans handles missing values and scaling automatically
96
+ clusterer = AutoKMeans(
97
+ max_k=8, # Try up to 8 clusters
98
+ method='silhouette', # Use silhouette score for k-selection
99
+ scale=True, # Scale features (important for clustering)
100
+ impute=True, # Handle missing values
101
+ impute_strategy='median', # Use median for imputation
102
+ ignore_non_numeric=True, # Silently skip non-numeric columns
103
+ random_state=42
104
+ )
105
+
106
+ # Fit and predict clusters
107
+ cluster_labels = clusterer.fit_predict(processed_df)
108
+
109
+ print(f"Optimal clusters found: {clusterer.n_clusters_}")
110
+ print(f"Cluster distribution: {np.bincount(cluster_labels)}")
111
+
112
+ # Add clusters back to original data for analysis
113
+ df['cluster'] = cluster_labels
114
+ print("\nCluster summary:")
115
+ print(df.groupby('cluster')[['revenue', 'customer_age', 'satisfaction']].mean())
116
+ ```
117
+
118
+ ### Sklearn Pipeline Integration
119
+
120
+ ```python
121
+ from sklearn.pipeline import Pipeline
122
+ from sklearn.preprocessing import StandardScaler
123
+
124
+ # Create a complete sklearn pipeline
125
+ ml_pipeline = Pipeline([
126
+ ('preprocessing', FeatureEngineeringPipeline.create_default()),
127
+ ('clustering', AutoKMeans(max_k=5, scale=True, impute=True))
128
+ ])
129
+
130
+ # One-line fit and predict
131
+ cluster_labels = ml_pipeline.fit_predict(df)
132
+ ```
133
+
134
+ ## 🔧 Advanced Usage
135
+
136
+ ### Custom Preprocessing Pipeline
137
+
138
+ ```python
139
+ from ravenclaw.preprocessing.df_encoders import (
140
+ StringTemporalConverter,
141
+ DateTimeConverter,
142
+ DayOfYearEncoder,
143
+ HourOfDayEncoder,
144
+ OneHotEncoder,
145
+ FeatureEngineeringPipeline
146
+ )
147
+
148
+ # Build custom pipeline with specific encoders
149
+ custom_pipeline = FeatureEngineeringPipeline([
150
+ StringTemporalConverter(), # String temporal → proper types
151
+ DateTimeConverter(), # datetime → day_of_year + hour_of_day
152
+ DayOfYearEncoder(), # day_of_year → sin/cos features
153
+ HourOfDayEncoder(), # hour_of_day → sin/cos features
154
+ OneHotEncoder(exclude_columns=['timestamp']) # Categorical → binary (skip temporal)
155
+ ])
156
+
157
+ result = custom_pipeline.fit_transform(df)
158
+ ```
159
+
160
+ ### Clustering with Column Selection
161
+
162
+ ```python
163
+ # Cluster only specific columns
164
+ clusterer = AutoKMeans(
165
+ include_columns=['revenue', 'customer_age', 'satisfaction'],
166
+ max_k=6,
167
+ method='calinski_harabasz',
168
+ impute=True,
169
+ impute_strategy='mean'
170
+ )
171
+
172
+ labels = clusterer.fit_predict(df)
173
+
174
+ # Get clustering diagnostics
175
+ diagnostics = clusterer.get_diagnostics()
176
+ print(f"Tried k values: {diagnostics['candidate_ks']}")
177
+ print(f"Scores: {diagnostics['scores']}")
178
+ ```
179
+
180
+ ### Individual Encoder Usage
181
+
182
+ ```python
183
+ from ravenclaw.preprocessing.df_encoders import StringTemporalConverter
184
+
185
+ # Just convert temporal strings
186
+ converter = StringTemporalConverter()
187
+ converter.fit(df)
188
+
189
+ # See what formats were learned
190
+ formats = converter.get_learned_formats()
191
+ print("Detected formats:", formats)
192
+
193
+ # Transform the data
194
+ converted_df = converter.transform(df)
195
+ ```
196
+
197
+ ## 🧠 How It Works
198
+
199
+ ### Intelligent Column Detection
200
+ Ravenclaw uses priority-based classification to handle ambiguous cases:
201
+ ```
202
+ datetime > date > time > day_of_week > day_of_year > hour_of_day > categorical
203
+ ```
204
+
205
+ ### Automatic K-Selection Methods
206
+ - **Silhouette Score**: Measures cluster cohesion and separation
207
+ - **Calinski-Harabasz**: Ratio of between-cluster to within-cluster variance
208
+ - **Davies-Bouldin**: Average similarity between clusters
209
+ - **Elbow Method**: Finds the "elbow" in the inertia curve
210
+
211
+ ### Built-in Imputation
212
+ AutoKMeans includes sklearn's SimpleImputer with strategies:
213
+ - `'mean'`: Replace with column mean (numeric only)
214
+ - `'median'`: Replace with column median (numeric only)
215
+ - `'most_frequent'`: Replace with mode (works for all types)
216
+ - `'constant'`: Replace with a constant value
217
+
218
+ ## 📊 What You Get
219
+
220
+ ### Before Ravenclaw
221
+ ```python
222
+ # Manual feature engineering pain
223
+ df['hour'] = pd.to_datetime(df['timestamp']).dt.hour
224
+ df['day_of_year'] = pd.to_datetime(df['timestamp']).dt.dayofyear
225
+ df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
226
+ df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
227
+ # ... repeat for every temporal column
228
+ # ... handle missing values
229
+ # ... scale features
230
+ # ... try different k values
231
+ # ... compare clustering metrics
232
+ ```
233
+
234
+ ### After Ravenclaw
235
+ ```python
236
+ # One-liner magic ✨
237
+ pipeline = FeatureEngineeringPipeline.create_default()
238
+ processed_df = pipeline.fit_transform(df)
239
+ labels = AutoKMeans(max_k=8).fit_predict(processed_df)
240
+ ```
241
+
242
+ ## 🛠️ Development
243
+
244
+ ```bash
245
+ # Clone and setup
246
+ git clone https://github.com/idin/ravenclaw.git
247
+ cd ravenclaw
248
+
249
+ # Create conda environment
250
+ conda env create -f environment.yml
251
+ conda activate ravenclaw
252
+
253
+ # Install in development mode
254
+ pip install -e .
255
+
256
+ # Run tests (244 tests, all passing!)
257
+ pytest tests/
258
+ ```
259
+
260
+ ## 📈 Project Status
261
+
262
+ - ✅ **244 Tests Passing** - Comprehensive test coverage
263
+ - ✅ **Production Ready** - Used in real ML workflows
264
+ - ✅ **Zero Warnings** - Clean, maintainable codebase
265
+ - ✅ **Sklearn Compatible** - Drop-in replacement for standard tools
266
+ - ✅ **Type Safe** - Full type hints and error handling
267
+
268
+ ## 🎯 Perfect For
269
+
270
+ - **Data Scientists**: Spend less time on preprocessing, more on insights
271
+ - **ML Engineers**: Robust, tested pipelines for production
272
+ - **Analysts**: Intelligent automation for common data tasks
273
+ - **Anyone**: Who works with messy, real-world pandas DataFrames
274
+
275
+ ## 📄 License
276
+
277
+ MIT License - Use it, love it, contribute to it!
278
+
279
+ ---
280
+
281
+ *Ravenclaw: Because your data deserves intelligent preprocessing* 🧙‍♂️✨
@@ -0,0 +1,255 @@
1
+ # Ravenclaw - Intelligent Data Preprocessing and Clustering
2
+
3
+ A comprehensive toolkit for automated feature engineering and clustering with pandas DataFrames. Ravenclaw intelligently detects column types, converts temporal strings, creates cyclical encodings, and performs automatic clustering - all with minimal configuration.
4
+
5
+ ## 🎯 Key Features
6
+
7
+ ### **Intelligent Preprocessing Pipeline**
8
+ - **Automatic Detection**: Identifies datetime, date, time, and categorical columns in string format
9
+ - **Smart Conversion**: Converts string temporal data to proper types with format learning
10
+ - **Cyclical Encoding**: Creates sin/cos features for temporal data (perfect for ML models)
11
+ - **One-Hot Encoding**: Handles categorical variables with temporal safety checks
12
+ - **Sklearn Compatible**: Standard fit/transform interface for seamless integration
13
+
14
+ ### **Advanced Clustering**
15
+ - **AutoKMeans**: Automatically determines optimal number of clusters
16
+ - **Multiple Methods**: Silhouette, Calinski-Harabasz, Davies-Bouldin, and Elbow methods
17
+ - **Built-in Preprocessing**: Integrated scaling and imputation
18
+ - **Column Selection**: Flexible include/exclude functionality
19
+ - **Sklearn Interface**: Drop-in replacement for standard KMeans
20
+
21
+ ## 🚀 Quick Start
22
+
23
+ ### Installation
24
+
25
+ ```bash
26
+ pip install ravenclaw
27
+ ```
28
+
29
+ ### Complete ML Pipeline Example
30
+
31
+ Here's how to preprocess mixed data and cluster it in a single pipeline:
32
+
33
+ ```python
34
+ import pandas as pd
35
+ import numpy as np
36
+ from ravenclaw.preprocessing.df_encoders import FeatureEngineeringPipeline
37
+ from ravenclaw.clustering.kmeans import AutoKMeans
38
+ from sklearn.pipeline import Pipeline
39
+
40
+ # Create sample mixed data (the kind you get in real life!)
41
+ np.random.seed(42)
42
+ df = pd.DataFrame({
43
+ 'timestamp': ['2023-01-15 14:30:00', '2023-06-30 09:15:00', '2023-12-25 18:45:00'] * 50,
44
+ 'date_created': ['2023-01-15', '2023-06-30', '2023-12-25'] * 50,
45
+ 'time_of_day': ['14:30:00', '09:15:00', '18:45:00'] * 50,
46
+ 'category': ['Premium', 'Standard', 'Basic'] * 50,
47
+ 'region': ['North', 'South', 'East', 'West'] * 37 + ['North', 'South', 'East'],
48
+ 'revenue': np.random.normal(1000, 200, 150),
49
+ 'customer_age': np.random.randint(18, 80, 150),
50
+ 'satisfaction': np.random.uniform(1, 5, 150)
51
+ })
52
+
53
+ # Add some missing values (real data is messy!)
54
+ df.loc[np.random.choice(150, 10), 'revenue'] = np.nan
55
+ df.loc[np.random.choice(150, 5), 'satisfaction'] = np.nan
56
+
57
+ print(f"Original data: {df.shape[1]} columns")
58
+ print(f"Column types: {df.dtypes.value_counts().to_dict()}")
59
+
60
+ # Step 1: Feature Engineering Pipeline
61
+ # Automatically detects and converts temporal strings, creates cyclical features
62
+ preprocessor = FeatureEngineeringPipeline.create_default()
63
+ processed_df = preprocessor.fit_transform(df)
64
+
65
+ print(f"After preprocessing: {processed_df.shape[1]} columns")
66
+ print(f"New features: {list(processed_df.columns)}")
67
+
68
+ # Step 2: Automatic Clustering with Built-in Imputation
69
+ # AutoKMeans handles missing values and scaling automatically
70
+ clusterer = AutoKMeans(
71
+ max_k=8, # Try up to 8 clusters
72
+ method='silhouette', # Use silhouette score for k-selection
73
+ scale=True, # Scale features (important for clustering)
74
+ impute=True, # Handle missing values
75
+ impute_strategy='median', # Use median for imputation
76
+ ignore_non_numeric=True, # Silently skip non-numeric columns
77
+ random_state=42
78
+ )
79
+
80
+ # Fit and predict clusters
81
+ cluster_labels = clusterer.fit_predict(processed_df)
82
+
83
+ print(f"Optimal clusters found: {clusterer.n_clusters_}")
84
+ print(f"Cluster distribution: {np.bincount(cluster_labels)}")
85
+
86
+ # Add clusters back to original data for analysis
87
+ df['cluster'] = cluster_labels
88
+ print("\nCluster summary:")
89
+ print(df.groupby('cluster')[['revenue', 'customer_age', 'satisfaction']].mean())
90
+ ```
91
+
92
+ ### Sklearn Pipeline Integration
93
+
94
+ ```python
95
+ from sklearn.pipeline import Pipeline
96
+ from sklearn.preprocessing import StandardScaler
97
+
98
+ # Create a complete sklearn pipeline
99
+ ml_pipeline = Pipeline([
100
+ ('preprocessing', FeatureEngineeringPipeline.create_default()),
101
+ ('clustering', AutoKMeans(max_k=5, scale=True, impute=True))
102
+ ])
103
+
104
+ # One-line fit and predict
105
+ cluster_labels = ml_pipeline.fit_predict(df)
106
+ ```
107
+
108
+ ## 🔧 Advanced Usage
109
+
110
+ ### Custom Preprocessing Pipeline
111
+
112
+ ```python
113
+ from ravenclaw.preprocessing.df_encoders import (
114
+ StringTemporalConverter,
115
+ DateTimeConverter,
116
+ DayOfYearEncoder,
117
+ HourOfDayEncoder,
118
+ OneHotEncoder,
119
+ FeatureEngineeringPipeline
120
+ )
121
+
122
+ # Build custom pipeline with specific encoders
123
+ custom_pipeline = FeatureEngineeringPipeline([
124
+ StringTemporalConverter(), # String temporal → proper types
125
+ DateTimeConverter(), # datetime → day_of_year + hour_of_day
126
+ DayOfYearEncoder(), # day_of_year → sin/cos features
127
+ HourOfDayEncoder(), # hour_of_day → sin/cos features
128
+ OneHotEncoder(exclude_columns=['timestamp']) # Categorical → binary (skip temporal)
129
+ ])
130
+
131
+ result = custom_pipeline.fit_transform(df)
132
+ ```
133
+
134
+ ### Clustering with Column Selection
135
+
136
+ ```python
137
+ # Cluster only specific columns
138
+ clusterer = AutoKMeans(
139
+ include_columns=['revenue', 'customer_age', 'satisfaction'],
140
+ max_k=6,
141
+ method='calinski_harabasz',
142
+ impute=True,
143
+ impute_strategy='mean'
144
+ )
145
+
146
+ labels = clusterer.fit_predict(df)
147
+
148
+ # Get clustering diagnostics
149
+ diagnostics = clusterer.get_diagnostics()
150
+ print(f"Tried k values: {diagnostics['candidate_ks']}")
151
+ print(f"Scores: {diagnostics['scores']}")
152
+ ```
153
+
154
+ ### Individual Encoder Usage
155
+
156
+ ```python
157
+ from ravenclaw.preprocessing.df_encoders import StringTemporalConverter
158
+
159
+ # Just convert temporal strings
160
+ converter = StringTemporalConverter()
161
+ converter.fit(df)
162
+
163
+ # See what formats were learned
164
+ formats = converter.get_learned_formats()
165
+ print("Detected formats:", formats)
166
+
167
+ # Transform the data
168
+ converted_df = converter.transform(df)
169
+ ```
170
+
171
+ ## 🧠 How It Works
172
+
173
+ ### Intelligent Column Detection
174
+ Ravenclaw uses priority-based classification to handle ambiguous cases:
175
+ ```
176
+ datetime > date > time > day_of_week > day_of_year > hour_of_day > categorical
177
+ ```
178
+
179
+ ### Automatic K-Selection Methods
180
+ - **Silhouette Score**: Measures cluster cohesion and separation
181
+ - **Calinski-Harabasz**: Ratio of between-cluster to within-cluster variance
182
+ - **Davies-Bouldin**: Average similarity between clusters
183
+ - **Elbow Method**: Finds the "elbow" in the inertia curve
184
+
185
+ ### Built-in Imputation
186
+ AutoKMeans includes sklearn's SimpleImputer with strategies:
187
+ - `'mean'`: Replace with column mean (numeric only)
188
+ - `'median'`: Replace with column median (numeric only)
189
+ - `'most_frequent'`: Replace with mode (works for all types)
190
+ - `'constant'`: Replace with a constant value
191
+
192
+ ## 📊 What You Get
193
+
194
+ ### Before Ravenclaw
195
+ ```python
196
+ # Manual feature engineering pain
197
+ df['hour'] = pd.to_datetime(df['timestamp']).dt.hour
198
+ df['day_of_year'] = pd.to_datetime(df['timestamp']).dt.dayofyear
199
+ df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
200
+ df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
201
+ # ... repeat for every temporal column
202
+ # ... handle missing values
203
+ # ... scale features
204
+ # ... try different k values
205
+ # ... compare clustering metrics
206
+ ```
207
+
208
+ ### After Ravenclaw
209
+ ```python
210
+ # One-liner magic ✨
211
+ pipeline = FeatureEngineeringPipeline.create_default()
212
+ processed_df = pipeline.fit_transform(df)
213
+ labels = AutoKMeans(max_k=8).fit_predict(processed_df)
214
+ ```
215
+
216
+ ## 🛠️ Development
217
+
218
+ ```bash
219
+ # Clone and setup
220
+ git clone https://github.com/idin/ravenclaw.git
221
+ cd ravenclaw
222
+
223
+ # Create conda environment
224
+ conda env create -f environment.yml
225
+ conda activate ravenclaw
226
+
227
+ # Install in development mode
228
+ pip install -e .
229
+
230
+ # Run tests (244 tests, all passing!)
231
+ pytest tests/
232
+ ```
233
+
234
+ ## 📈 Project Status
235
+
236
+ - ✅ **244 Tests Passing** - Comprehensive test coverage
237
+ - ✅ **Production Ready** - Used in real ML workflows
238
+ - ✅ **Zero Warnings** - Clean, maintainable codebase
239
+ - ✅ **Sklearn Compatible** - Drop-in replacement for standard tools
240
+ - ✅ **Type Safe** - Full type hints and error handling
241
+
242
+ ## 🎯 Perfect For
243
+
244
+ - **Data Scientists**: Spend less time on preprocessing, more on insights
245
+ - **ML Engineers**: Robust, tested pipelines for production
246
+ - **Analysts**: Intelligent automation for common data tasks
247
+ - **Anyone**: Who works with messy, real-world pandas DataFrames
248
+
249
+ ## 📄 License
250
+
251
+ MIT License - Use it, love it, contribute to it!
252
+
253
+ ---
254
+
255
+ *Ravenclaw: Because your data deserves intelligent preprocessing* 🧙‍♂️✨
@@ -0,0 +1,23 @@
1
+ """Ravenclaw - Data Wrangling and Feature Engineering Package.
2
+
3
+ A comprehensive toolkit for data wrangling, feature engineering, and data cleaning
4
+ with pandas DataFrames. Provides intelligent column detection, feature encoding,
5
+ data preprocessing utilities, and advanced DataFrame manipulation functions.
6
+
7
+ Submodules:
8
+ - preprocessing: Feature engineering and data preprocessing utilities
9
+ - clustering: K-means clustering with automatic k-selection
10
+ - wrangling: DataFrame manipulation and analysis utilities
11
+
12
+ Usage:
13
+ from ravenclaw.preprocessing import column_detection
14
+ from ravenclaw.clustering import kmeans
15
+ from ravenclaw.wrangling import join_wisely, standardize_columns
16
+ """
17
+
18
+ __version__ = "0.1.0"
19
+ __author__ = "Idin"
20
+ __email__ = "py@idin.net"
21
+ __description__ = "Data wrangling and feature engineering toolkit for pandas DataFrames"
22
+
23
+ __all__ = []
@@ -0,0 +1,5 @@
1
+ """Clustering module for data analysis and machine learning."""
2
+
3
+ from .kmeans import find_optimal_k, cluster, AutoKMeans
4
+
5
+ __all__ = ["find_optimal_k", "cluster", "AutoKMeans"]
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from .k_selection import find_optimal_k
4
+ from .cluster import cluster
5
+ from .auto_kmeans import AutoKMeans
6
+
7
+ __all__ = ["find_optimal_k", "cluster", "AutoKMeans"]