@@ -424,4 +424,32 @@ def filter(self, obj: MarketDataFrame) -> MarketDataFrame: ...
424
424
def filter (self , obj : pd .Series ) -> pd .Series : ...
425
425
def filter (self , obj : pd .DataFrame | MarketDataFrame | pd .Series ) -> pd .DataFrame | pd .Series :
426
426
assert isinstance (obj .index , pd .DatetimeIndex )
427
- return obj .between_time (start_time = self .start , end_time = self .end , inclusive = self .inclusive ) # type: ignore
427
+ return obj .between_time (start_time = self .start , end_time = self .end , inclusive = self .inclusive ) # type: ignore
428
+
429
+
430
+ def copy_constant_col_to_all_rows (df : pd .DataFrame , cname : str ) -> pd .DataFrame :
431
+ """
432
+ Copy a constant column to all rows, allowing for missing values in the column as long
433
+ as the there is only one unique non-missing value in the column.
434
+
435
+ Args:
436
+ df (pd.DataFrame): Input DataFrame.
437
+ cname (str): Name of the column to copy.
438
+
439
+ Returns:
440
+ pd.DataFrame: DataFrame with the constant column copied to all rows.
441
+ """
442
+
443
+ if cname not in df .columns :
444
+ raise ValueError (f'{ cname } not in df.columns' )
445
+
446
+ unique_vals = set (df [cname ].dropna ().unique ())
447
+
448
+ if len (unique_vals ) > 1 :
449
+ raise ValueError (f'{ cname } has more than one unique value' )
450
+ if len (unique_vals ) == 0 :
451
+ raise ValueError (f'{ cname } has no unique values' )
452
+
453
+ df .loc [:, cname ] = unique_vals .pop ()
454
+
455
+ return df
0 commit comments