(batch: pd.DataFrame)
| 339 | import ray |
| 340 | |
| 341 | def join_batch_with_features(batch: pd.DataFrame) -> pd.DataFrame: |
| 342 | features = ray.get(feature_ref) |
| 343 | if original_join_keys: |
| 344 | feature_join_keys = original_join_keys |
| 345 | entity_join_keys = join_keys |
| 346 | else: |
| 347 | feature_join_keys = join_keys |
| 348 | entity_join_keys = join_keys |
| 349 | feature_cols = [timestamp_field] + feature_join_keys + requested_feats |
| 350 | available_feature_cols = [ |
| 351 | col for col in feature_cols if col in features.columns |
| 352 | ] |
| 353 | features_filtered = features[available_feature_cols].copy() |
| 354 | |
| 355 | batch = normalize_timestamp_columns(batch, timestamp_field, inplace=True) |
| 356 | features_filtered = normalize_timestamp_columns( |
| 357 | features_filtered, timestamp_field, inplace=True |
| 358 | ) |
| 359 | if not entity_join_keys: |
| 360 | batch_sorted = batch.sort_values(timestamp_field).reset_index(drop=True) |
| 361 | features_sorted = features_filtered.sort_values( |
| 362 | timestamp_field |
| 363 | ).reset_index(drop=True) |
| 364 | result = pd.merge_asof( |
| 365 | batch_sorted, |
| 366 | features_sorted, |
| 367 | on=timestamp_field, |
| 368 | direction="backward", |
| 369 | ) |
| 370 | else: |
| 371 | for key in entity_join_keys: |
| 372 | if key not in batch.columns: |
| 373 | batch[key] = np.nan |
| 374 | for key in feature_join_keys: |
| 375 | if key not in features_filtered.columns: |
| 376 | features_filtered[key] = np.nan |
| 377 | batch_clean = batch.dropna( |
| 378 | subset=entity_join_keys + [timestamp_field] |
| 379 | ).copy() |
| 380 | features_clean = features_filtered.dropna( |
| 381 | subset=feature_join_keys + [timestamp_field] |
| 382 | ).copy() |
| 383 | if batch_clean.empty or features_clean.empty: |
| 384 | return batch.head(0) |
| 385 | if timestamp_field in batch_clean.columns: |
| 386 | batch_sorted = batch_clean.sort_values( |
| 387 | timestamp_field, ascending=True |
| 388 | ).reset_index(drop=True) |
| 389 | else: |
| 390 | batch_sorted = batch_clean.reset_index(drop=True) |
| 391 | right_sort_columns = [ |
| 392 | k for k in feature_join_keys if k in features_clean.columns |
| 393 | ] |
| 394 | if timestamp_field in features_clean.columns: |
| 395 | right_sort_columns.append(timestamp_field) |
| 396 | if right_sort_columns: |
| 397 | features_clean = features_clean.drop_duplicates( |
| 398 | subset=right_sort_columns, keep="last" |
nothing calls this directly
no test coverage detected