gamsapi 52.5.0__cp312-cp312-win_amd64.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.
Files changed (257) hide show
  1. gams/__init__.py +27 -0
  2. gams/_version.py +1 -0
  3. gams/connect/__init__.py +28 -0
  4. gams/connect/agents/__init__.py +24 -0
  5. gams/connect/agents/_excel/__init__.py +32 -0
  6. gams/connect/agents/_excel/excelagent.py +312 -0
  7. gams/connect/agents/_excel/workbook.py +155 -0
  8. gams/connect/agents/_sqlconnectors/__init__.py +42 -0
  9. gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
  10. gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
  11. gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
  12. gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
  13. gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
  14. gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
  15. gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
  16. gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
  17. gams/connect/agents/concatenate.py +440 -0
  18. gams/connect/agents/connectagent.py +743 -0
  19. gams/connect/agents/csvreader.py +675 -0
  20. gams/connect/agents/csvwriter.py +151 -0
  21. gams/connect/agents/domainwriter.py +143 -0
  22. gams/connect/agents/excelreader.py +756 -0
  23. gams/connect/agents/excelwriter.py +467 -0
  24. gams/connect/agents/filter.py +223 -0
  25. gams/connect/agents/gamsreader.py +112 -0
  26. gams/connect/agents/gamswriter.py +239 -0
  27. gams/connect/agents/gdxreader.py +109 -0
  28. gams/connect/agents/gdxwriter.py +146 -0
  29. gams/connect/agents/labelmanipulator.py +303 -0
  30. gams/connect/agents/projection.py +539 -0
  31. gams/connect/agents/pythoncode.py +71 -0
  32. gams/connect/agents/rawcsvreader.py +248 -0
  33. gams/connect/agents/rawexcelreader.py +312 -0
  34. gams/connect/agents/schema/CSVReader.yaml +92 -0
  35. gams/connect/agents/schema/CSVWriter.yaml +44 -0
  36. gams/connect/agents/schema/Concatenate.yaml +52 -0
  37. gams/connect/agents/schema/DomainWriter.yaml +25 -0
  38. gams/connect/agents/schema/ExcelReader.yaml +121 -0
  39. gams/connect/agents/schema/ExcelWriter.yaml +78 -0
  40. gams/connect/agents/schema/Filter.yaml +74 -0
  41. gams/connect/agents/schema/GAMSReader.yaml +20 -0
  42. gams/connect/agents/schema/GAMSWriter.yaml +47 -0
  43. gams/connect/agents/schema/GDXReader.yaml +23 -0
  44. gams/connect/agents/schema/GDXWriter.yaml +32 -0
  45. gams/connect/agents/schema/LabelManipulator.yaml +99 -0
  46. gams/connect/agents/schema/Projection.yaml +24 -0
  47. gams/connect/agents/schema/PythonCode.yaml +6 -0
  48. gams/connect/agents/schema/RawCSVReader.yaml +34 -0
  49. gams/connect/agents/schema/RawExcelReader.yaml +42 -0
  50. gams/connect/agents/schema/SQLReader.yaml +75 -0
  51. gams/connect/agents/schema/SQLWriter.yaml +103 -0
  52. gams/connect/agents/sqlreader.py +301 -0
  53. gams/connect/agents/sqlwriter.py +276 -0
  54. gams/connect/connectdatabase.py +275 -0
  55. gams/connect/connectvalidator.py +93 -0
  56. gams/connect/errors.py +34 -0
  57. gams/control/__init__.py +136 -0
  58. gams/control/database.py +2231 -0
  59. gams/control/execution.py +1900 -0
  60. gams/control/options.py +2792 -0
  61. gams/control/workspace.py +1198 -0
  62. gams/core/__init__.py +24 -0
  63. gams/core/cfg/__init__.py +26 -0
  64. gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
  65. gams/core/cfg/cfgmcc.py +519 -0
  66. gams/core/dct/__init__.py +26 -0
  67. gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
  68. gams/core/dct/dctmcc.py +574 -0
  69. gams/core/embedded/__init__.py +26 -0
  70. gams/core/embedded/gamsemb.py +1024 -0
  71. gams/core/emp/__init__.py +24 -0
  72. gams/core/emp/emplexer.py +89 -0
  73. gams/core/emp/empyacc.py +281 -0
  74. gams/core/gdx/__init__.py +26 -0
  75. gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
  76. gams/core/gdx/gdxcc.py +866 -0
  77. gams/core/gev/__init__.py +26 -0
  78. gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
  79. gams/core/gev/gevmcc.py +855 -0
  80. gams/core/gmd/__init__.py +26 -0
  81. gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
  82. gams/core/gmd/gmdcc.py +917 -0
  83. gams/core/gmo/__init__.py +26 -0
  84. gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
  85. gams/core/gmo/gmomcc.py +2046 -0
  86. gams/core/idx/__init__.py +26 -0
  87. gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
  88. gams/core/idx/idxcc.py +510 -0
  89. gams/core/numpy/__init__.py +29 -0
  90. gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
  91. gams/core/numpy/gams2numpy.py +1048 -0
  92. gams/core/opt/__init__.py +26 -0
  93. gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
  94. gams/core/opt/optcc.py +840 -0
  95. gams/engine/__init__.py +204 -0
  96. gams/engine/api/__init__.py +13 -0
  97. gams/engine/api/auth_api.py +7653 -0
  98. gams/engine/api/cleanup_api.py +751 -0
  99. gams/engine/api/default_api.py +887 -0
  100. gams/engine/api/hypercube_api.py +2629 -0
  101. gams/engine/api/jobs_api.py +5229 -0
  102. gams/engine/api/licenses_api.py +2220 -0
  103. gams/engine/api/namespaces_api.py +7783 -0
  104. gams/engine/api/usage_api.py +5627 -0
  105. gams/engine/api/users_api.py +5931 -0
  106. gams/engine/api_client.py +804 -0
  107. gams/engine/api_response.py +21 -0
  108. gams/engine/configuration.py +601 -0
  109. gams/engine/exceptions.py +216 -0
  110. gams/engine/models/__init__.py +86 -0
  111. gams/engine/models/bad_input.py +89 -0
  112. gams/engine/models/cleanable_job_result.py +104 -0
  113. gams/engine/models/cleanable_job_result_page.py +113 -0
  114. gams/engine/models/engine_license.py +107 -0
  115. gams/engine/models/files_not_found.py +93 -0
  116. gams/engine/models/forwarded_token_response.py +112 -0
  117. gams/engine/models/generic_key_value_pair.py +89 -0
  118. gams/engine/models/hypercube.py +160 -0
  119. gams/engine/models/hypercube_page.py +111 -0
  120. gams/engine/models/hypercube_summary.py +91 -0
  121. gams/engine/models/hypercube_token.py +97 -0
  122. gams/engine/models/identity_provider.py +107 -0
  123. gams/engine/models/identity_provider_ldap.py +121 -0
  124. gams/engine/models/identity_provider_oauth2.py +146 -0
  125. gams/engine/models/identity_provider_oauth2_scope.py +89 -0
  126. gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
  127. gams/engine/models/identity_provider_oidc.py +133 -0
  128. gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
  129. gams/engine/models/inex.py +91 -0
  130. gams/engine/models/invitation.py +136 -0
  131. gams/engine/models/invitation_quota.py +106 -0
  132. gams/engine/models/invitation_token.py +87 -0
  133. gams/engine/models/job.py +165 -0
  134. gams/engine/models/job_no_text_entry.py +138 -0
  135. gams/engine/models/job_no_text_entry_page.py +111 -0
  136. gams/engine/models/license.py +91 -0
  137. gams/engine/models/log_piece.py +96 -0
  138. gams/engine/models/message.py +87 -0
  139. gams/engine/models/message_and_token.py +99 -0
  140. gams/engine/models/message_with_webhook_id.py +89 -0
  141. gams/engine/models/model_auth_token.py +87 -0
  142. gams/engine/models/model_configuration.py +125 -0
  143. gams/engine/models/model_default_instance.py +99 -0
  144. gams/engine/models/model_default_user_instance.py +98 -0
  145. gams/engine/models/model_hypercube_job.py +106 -0
  146. gams/engine/models/model_hypercube_usage.py +130 -0
  147. gams/engine/models/model_instance_info.py +116 -0
  148. gams/engine/models/model_instance_info_full.py +123 -0
  149. gams/engine/models/model_instance_pool_info.py +112 -0
  150. gams/engine/models/model_job_labels.py +179 -0
  151. gams/engine/models/model_job_usage.py +133 -0
  152. gams/engine/models/model_pool_usage.py +124 -0
  153. gams/engine/models/model_usage.py +115 -0
  154. gams/engine/models/model_user.py +96 -0
  155. gams/engine/models/model_userinstance_info.py +119 -0
  156. gams/engine/models/model_userinstancepool_info.py +95 -0
  157. gams/engine/models/model_version.py +91 -0
  158. gams/engine/models/models.py +120 -0
  159. gams/engine/models/namespace.py +104 -0
  160. gams/engine/models/namespace_quota.py +96 -0
  161. gams/engine/models/namespace_with_permission.py +96 -0
  162. gams/engine/models/not_found.py +91 -0
  163. gams/engine/models/password_policy.py +97 -0
  164. gams/engine/models/perm_and_username.py +89 -0
  165. gams/engine/models/quota.py +117 -0
  166. gams/engine/models/quota_exceeded.py +97 -0
  167. gams/engine/models/status_code_meaning.py +89 -0
  168. gams/engine/models/stream_entry.py +89 -0
  169. gams/engine/models/system_wide_license.py +92 -0
  170. gams/engine/models/text_entries.py +87 -0
  171. gams/engine/models/text_entry.py +101 -0
  172. gams/engine/models/time_span.py +95 -0
  173. gams/engine/models/time_span_pool_worker.py +99 -0
  174. gams/engine/models/token_forward_error.py +87 -0
  175. gams/engine/models/user.py +127 -0
  176. gams/engine/models/user_group_member.py +96 -0
  177. gams/engine/models/user_groups.py +108 -0
  178. gams/engine/models/vapid_info.py +87 -0
  179. gams/engine/models/webhook.py +138 -0
  180. gams/engine/models/webhook_parameterized_event.py +99 -0
  181. gams/engine/py.typed +0 -0
  182. gams/engine/rest.py +258 -0
  183. gams/magic/__init__.py +32 -0
  184. gams/magic/gams_magic.py +142 -0
  185. gams/magic/interactive.py +402 -0
  186. gams/tools/__init__.py +30 -0
  187. gams/tools/errors.py +34 -0
  188. gams/tools/toolcollection/__init__.py +24 -0
  189. gams/tools/toolcollection/alg/__init__.py +24 -0
  190. gams/tools/toolcollection/alg/rank.py +51 -0
  191. gams/tools/toolcollection/data/__init__.py +24 -0
  192. gams/tools/toolcollection/data/csvread.py +444 -0
  193. gams/tools/toolcollection/data/csvwrite.py +311 -0
  194. gams/tools/toolcollection/data/exceldump.py +47 -0
  195. gams/tools/toolcollection/data/sqlitewrite.py +276 -0
  196. gams/tools/toolcollection/gdxservice/__init__.py +24 -0
  197. gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
  198. gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
  199. gams/tools/toolcollection/linalg/__init__.py +24 -0
  200. gams/tools/toolcollection/linalg/cholesky.py +57 -0
  201. gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
  202. gams/tools/toolcollection/linalg/eigenvector.py +58 -0
  203. gams/tools/toolcollection/linalg/invert.py +55 -0
  204. gams/tools/toolcollection/linalg/ols.py +138 -0
  205. gams/tools/toolcollection/tooltemplate.py +321 -0
  206. gams/tools/toolcollection/win32/__init__.py +24 -0
  207. gams/tools/toolcollection/win32/excelmerge.py +93 -0
  208. gams/tools/toolcollection/win32/exceltalk.py +76 -0
  209. gams/tools/toolcollection/win32/msappavail.py +49 -0
  210. gams/tools/toolcollection/win32/shellexecute.py +54 -0
  211. gams/tools/tools.py +116 -0
  212. gams/transfer/__init__.py +35 -0
  213. gams/transfer/_abcs/__init__.py +37 -0
  214. gams/transfer/_abcs/container_abcs.py +433 -0
  215. gams/transfer/_internals/__init__.py +63 -0
  216. gams/transfer/_internals/algorithms.py +436 -0
  217. gams/transfer/_internals/casepreservingdict.py +124 -0
  218. gams/transfer/_internals/constants.py +270 -0
  219. gams/transfer/_internals/domainviolation.py +103 -0
  220. gams/transfer/_internals/specialvalues.py +172 -0
  221. gams/transfer/containers/__init__.py +26 -0
  222. gams/transfer/containers/_container.py +1794 -0
  223. gams/transfer/containers/_io/__init__.py +28 -0
  224. gams/transfer/containers/_io/containers.py +164 -0
  225. gams/transfer/containers/_io/gdx.py +1029 -0
  226. gams/transfer/containers/_io/gmd.py +872 -0
  227. gams/transfer/containers/_mixins/__init__.py +26 -0
  228. gams/transfer/containers/_mixins/ccc.py +1274 -0
  229. gams/transfer/syms/__init__.py +33 -0
  230. gams/transfer/syms/_methods/__init__.py +24 -0
  231. gams/transfer/syms/_methods/tables.py +120 -0
  232. gams/transfer/syms/_methods/toDict.py +115 -0
  233. gams/transfer/syms/_methods/toList.py +83 -0
  234. gams/transfer/syms/_methods/toValue.py +60 -0
  235. gams/transfer/syms/_mixins/__init__.py +32 -0
  236. gams/transfer/syms/_mixins/equals.py +626 -0
  237. gams/transfer/syms/_mixins/generateRecords.py +499 -0
  238. gams/transfer/syms/_mixins/pivot.py +313 -0
  239. gams/transfer/syms/_mixins/pve.py +627 -0
  240. gams/transfer/syms/_mixins/sa.py +27 -0
  241. gams/transfer/syms/_mixins/sapve.py +27 -0
  242. gams/transfer/syms/_mixins/saua.py +27 -0
  243. gams/transfer/syms/_mixins/sauapve.py +199 -0
  244. gams/transfer/syms/_mixins/spve.py +1528 -0
  245. gams/transfer/syms/_mixins/ve.py +936 -0
  246. gams/transfer/syms/container_syms/__init__.py +31 -0
  247. gams/transfer/syms/container_syms/_alias.py +984 -0
  248. gams/transfer/syms/container_syms/_equation.py +333 -0
  249. gams/transfer/syms/container_syms/_parameter.py +973 -0
  250. gams/transfer/syms/container_syms/_set.py +604 -0
  251. gams/transfer/syms/container_syms/_universe_alias.py +461 -0
  252. gams/transfer/syms/container_syms/_variable.py +321 -0
  253. gamsapi-52.5.0.dist-info/METADATA +150 -0
  254. gamsapi-52.5.0.dist-info/RECORD +257 -0
  255. gamsapi-52.5.0.dist-info/WHEEL +5 -0
  256. gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
  257. gamsapi-52.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,313 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ from gams.transfer._internals import SpecialValues
27
+ import pandas as pd
28
+ from typing import Optional, Union
29
+
30
+ major, minor, *_ = pd.__version__.split(".")
31
+
32
+
33
+ class PivotBase:
34
+ def pivot(self, *args):
35
+ index, columns = args
36
+
37
+ #
38
+ # ARG: self
39
+ if self.dimension < 2:
40
+ raise Exception(
41
+ "Pivoting operations only possible on symbols with dimension > 1, "
42
+ f"symbol dimension is {self.dimension}"
43
+ )
44
+
45
+ #
46
+ # ARG: index
47
+ if not isinstance(index, (str, list, type(None))):
48
+ raise TypeError("Argument 'index' must be type str, list or NoneType")
49
+
50
+ # set defaults
51
+ if index is None:
52
+ index = self.records.columns[: self.dimension - 1].tolist()
53
+
54
+ if isinstance(index, str):
55
+ index = [index]
56
+
57
+ #
58
+ # ARG: columns
59
+ if not isinstance(columns, (str, list, type(None))):
60
+ raise TypeError("Argument 'columns' must be type str, list, or NoneType")
61
+
62
+ # set defaults
63
+ if columns is None:
64
+ columns = self.records.columns[self.dimension - 1 : self.dimension].tolist()
65
+
66
+ if isinstance(columns, str):
67
+ columns = [columns]
68
+
69
+ #
70
+ # ARG: index & columns
71
+ if set(index + columns) != set(self.domain_labels):
72
+ raise Exception(
73
+ "Must specify all domain_labels to pivot in either 'index' or 'columns' "
74
+ f"arguments, user did not specify: {set(self.domain_labels) - set(index+columns)}"
75
+ )
76
+
77
+ return index, columns
78
+
79
+
80
+ class PivotSetMixin(PivotBase):
81
+ def pivot(
82
+ self,
83
+ index: Optional[Union[str, list]] = None,
84
+ columns: Optional[Union[str, list]] = None,
85
+ fill_value: Optional[Union[int, float, str]] = None,
86
+ ) -> pd.DataFrame:
87
+ """
88
+ Convenience function to pivot records into a new shape (only symbols with >1D can be pivoted)
89
+
90
+ Parameters
91
+ ----------
92
+ index : str | list, optional
93
+ If index is None then it is set to dimensions [0..dimension-1], by default None
94
+ columns : str | list, optional
95
+ If columns is None then it is set to the last dimension, by default None
96
+ fill_value : int | float | str, optional
97
+ Missing values in the pivot will take the value provided by fill_value, by default None
98
+
99
+ Returns
100
+ -------
101
+ DataFrame
102
+ Pivoted records dataframe
103
+ """
104
+ # check & set
105
+ index, columns = super().pivot(index, columns)
106
+ value = "value"
107
+
108
+ #
109
+ # ARG: fill_value
110
+ # set defaults
111
+ if fill_value is None:
112
+ fill_value = False
113
+
114
+ # processing for Sets
115
+ df = self.records.copy()
116
+ df.drop(columns=["element_text"], inplace=True)
117
+ df.insert(self.dimension, value, True)
118
+
119
+ # do the pivot
120
+ df = df.pivot(index=index, columns=columns, values=value)
121
+
122
+ # fill missing values
123
+ if (int(major), int(minor)) >= (2, 2):
124
+ with pd.option_context("future.no_silent_downcasting", True):
125
+ df.fillna(fill_value, inplace=True)
126
+ else:
127
+ df.fillna(fill_value, inplace=True)
128
+
129
+ # cast column types
130
+ if isinstance(fill_value, bool):
131
+ df = df.astype(bool)
132
+ else:
133
+ df = df.infer_objects()
134
+
135
+ df.index.names = [None] * len(index)
136
+ df.columns.names = [None] * len(columns)
137
+
138
+ return df
139
+
140
+
141
+ class PivotParameterMixin(PivotBase):
142
+ def pivot(
143
+ self,
144
+ index: Optional[Union[str, list]] = None,
145
+ columns: Optional[Union[str, list]] = None,
146
+ fill_value: Optional[Union[int, float, str]] = None,
147
+ ) -> pd.DataFrame:
148
+ """
149
+ Convenience function to pivot records into a new shape (only symbols with >1D can be pivoted)
150
+
151
+ Parameters
152
+ ----------
153
+ index : str | list, optional
154
+ If index is None then it is set to dimensions [0..dimension-1], by default None
155
+ columns : str | list, optional
156
+ If columns is None then it is set to the last dimension, by default None
157
+ fill_value : int | float | str, optional
158
+ Missing values in the pivot will take the value provided by fill_value, by default None
159
+
160
+ Returns
161
+ -------
162
+ DataFrame
163
+ Pivoted records dataframe
164
+ """
165
+ # check & set
166
+ index, columns = super().pivot(index, columns)
167
+ value = "value"
168
+
169
+ #
170
+ # ARG: fill_value
171
+ # set defaults
172
+ if fill_value is None:
173
+ fill_value = 0.0
174
+
175
+ # do the pivot
176
+ df = self.records[self.domain_labels + [value]]
177
+
178
+ if any(i != i for i in df[value]):
179
+ has_nans = True
180
+ else:
181
+ has_nans = False
182
+
183
+ # do the pivot
184
+ df = df.pivot(index=index, columns=columns, values=value)
185
+ stored_columns = df.columns
186
+
187
+ # fill missing values
188
+ if (int(major), int(minor)) >= (2, 2):
189
+ with pd.option_context("future.no_silent_downcasting", True):
190
+ df.fillna(fill_value, inplace=True)
191
+ else:
192
+ df.fillna(fill_value, inplace=True)
193
+
194
+ # need to restore proper special values
195
+ if has_nans:
196
+ specnans = self.findSpecialValues(
197
+ [SpecialValues.UNDEF, SpecialValues.NA], column=value
198
+ )
199
+
200
+ idx = list(zip(*[specnans[i] for i in index]))
201
+ col = list(zip(*[specnans[i] for i in columns]))
202
+ for n, (i, c) in zip(specnans.index, zip(idx, col)):
203
+ df.loc[i, c] = specnans.loc[n, value]
204
+
205
+ df.columns = stored_columns
206
+
207
+ # cast column types
208
+ if isinstance(fill_value, float):
209
+ df = df.astype(float)
210
+ else:
211
+ df = df.infer_objects()
212
+
213
+ df.index.names = [None] * len(index)
214
+ df.columns.names = [None] * len(columns)
215
+
216
+ return df
217
+
218
+
219
+ class PivotVariableMixin(PivotBase):
220
+ def pivot(
221
+ self,
222
+ index: Optional[Union[str, list]] = None,
223
+ columns: Optional[Union[str, list]] = None,
224
+ value: Optional[str] = None,
225
+ fill_value: Optional[Union[int, float, str]] = None,
226
+ ) -> pd.DataFrame:
227
+ """
228
+ Convenience function to pivot records into a new shape (only symbols with >1D can be pivoted)
229
+
230
+ Parameters
231
+ ----------
232
+ index : str | list, optional
233
+ If index is None then it is set to dimensions [0..dimension-1], by default None
234
+ columns : str | list, optional
235
+ If columns is None then it is set to the last dimension, by default None
236
+ value : str, optional
237
+ If value is None then the level values will be pivoted, by default None
238
+ fill_value : int | float | str, optional
239
+ Missing values in the pivot will take the value provided by fill_value, by default None
240
+
241
+ Returns
242
+ -------
243
+ DataFrame
244
+ Pivoted records dataframe
245
+ """
246
+ # check & set
247
+ index, columns = super().pivot(index, columns)
248
+
249
+ #
250
+ # ARG: value
251
+ # set defaults
252
+ if not isinstance(value, (str, type(None))):
253
+ raise TypeError("Argument 'value' must be type str or NoneType")
254
+
255
+ if value is None:
256
+ value = "level"
257
+
258
+ if value not in self._attributes:
259
+ raise TypeError(
260
+ f"Argument 'value' must be one of the following symbol attributes: {self._attributes}"
261
+ )
262
+
263
+ #
264
+ # ARG: fill_value
265
+ # set defaults
266
+ if fill_value is None:
267
+ fill_value = 0.0
268
+
269
+ # do the pivot
270
+ df = self.records[self.domain_labels + [value]]
271
+
272
+ if any(i != i for i in df[value]):
273
+ has_nans = True
274
+ else:
275
+ has_nans = False
276
+
277
+ # do the pivot
278
+ df = df.pivot(index=index, columns=columns, values=value)
279
+ stored_columns = df.columns
280
+
281
+ # fill missing values
282
+ if (int(major), int(minor)) >= (2, 2):
283
+ with pd.option_context("future.no_silent_downcasting", True):
284
+ df.fillna(fill_value, inplace=True)
285
+ else:
286
+ df.fillna(fill_value, inplace=True)
287
+
288
+ # need to restore proper special values
289
+ if has_nans:
290
+ specnans = self.findSpecialValues(
291
+ [SpecialValues.UNDEF, SpecialValues.NA], column=value
292
+ )
293
+
294
+ idx = list(zip(*[specnans[i] for i in index]))
295
+ col = list(zip(*[specnans[i] for i in columns]))
296
+ for n, (i, c) in zip(specnans.index, zip(idx, col)):
297
+ df.loc[i, c] = specnans.loc[n, value]
298
+
299
+ df.columns = stored_columns
300
+
301
+ # cast column types
302
+ if isinstance(fill_value, float):
303
+ df = df.astype(float)
304
+ else:
305
+ df = df.infer_objects()
306
+
307
+ df.index.names = [None] * len(index)
308
+ df.columns.names = [None] * len(columns)
309
+
310
+ return df
311
+
312
+
313
+ class PivotEquationMixin(PivotVariableMixin): ...