Coverage for mlos_core/mlos_core/util.py: 95%

19 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 00:44 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5"""Internal helper functions for mlos_core package.""" 

6 

7from typing import Optional, Union 

8 

9import pandas as pd 

10from ConfigSpace import Configuration, ConfigurationSpace 

11 

12 

13def compare_optional_series(left: Optional[pd.Series], right: Optional[pd.Series]) -> bool: 

14 """ 

15 Compare Series that may also be None. 

16 

17 Parameters 

18 ---------- 

19 left : Optional[pandas.Series] 

20 The left Series to compare 

21 right : Optional[pandas.Series] 

22 The right Series to compare 

23 

24 Returns 

25 ------- 

26 bool 

27 Compare the equality of two Optional[pd.Series] objects 

28 """ 

29 if isinstance(left, pd.Series) and isinstance(right, pd.Series): 

30 return left.equals(right) 

31 return left is None and right is None 

32 

33 

34def compare_optional_dataframe( 

35 left: Optional[pd.DataFrame], 

36 right: Optional[pd.DataFrame], 

37) -> bool: 

38 """ 

39 Compare DataFrames that may also be None. 

40 

41 Parameters 

42 ---------- 

43 left : Optional[pandas.DataFrame] 

44 The left DataFrame to compare 

45 right : Optional[pandas.DataFrame] 

46 The right DataFrame to compare 

47 

48 Returns 

49 ------- 

50 bool 

51 Compare the equality of two Optional[pd.DataFrame] objects 

52 """ 

53 if isinstance(left, pd.DataFrame) and isinstance(right, pd.DataFrame): 

54 return left.equals(right) 

55 return left is None and right is None 

56 

57 

58def config_to_series(config: Configuration) -> pd.Series: 

59 """ 

60 Converts a ConfigSpace config to a Series. 

61 

62 Parameters 

63 ---------- 

64 config : ConfigSpace.Configuration 

65 The config to convert. 

66 

67 Returns 

68 ------- 

69 pandas.Series 

70 A Series, containing the config's parameters. 

71 """ 

72 series: pd.Series = pd.Series(dict(config)) # needed for type hinting 

73 return series 

74 

75 

76def drop_nulls(d: dict) -> dict: 

77 """ 

78 Remove all key-value pairs where the value is None. 

79 

80 Parameters 

81 ---------- 

82 d : dict 

83 The dictionary to clean. 

84 

85 Returns 

86 ------- 

87 dict 

88 The cleaned dictionary. 

89 """ 

90 return {k: v for k, v in d.items() if v is not None} 

91 

92 

93def normalize_config( 

94 config_space: ConfigurationSpace, 

95 config: Union[Configuration, dict], 

96) -> Configuration: 

97 """ 

98 Convert a dictionary to a valid ConfigSpace configuration. 

99 

100 Some optimizers and adapters ignore ConfigSpace conditionals when proposing new 

101 configurations. We have to manually remove inactive hyperparameters such suggestions. 

102 

103 Parameters 

104 ---------- 

105 config_space : ConfigSpace.ConfigurationSpace 

106 The parameter space to use. 

107 config : dict 

108 The configuration to convert. 

109 

110 Returns 

111 ------- 

112 cs_config: ConfigSpace.Configuration 

113 A valid ConfigSpace configuration with inactive parameters removed. 

114 """ 

115 cs_config = Configuration(config_space, values=config, allow_inactive_with_values=True) 

116 return Configuration( 

117 config_space, 

118 values={key: cs_config[key] for key in config_space.get_active_hyperparameters(cs_config)}, 

119 )