okstra 0.107.2 → 0.109.0

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 (649) hide show
  1. package/package.json +1 -1
  2. package/runtime/BUILD.json +2 -2
  3. package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
  4. package/runtime/prompts/profiles/_common-contract.md +3 -2
  5. package/runtime/python/okstra_ctl/graphify_cmd.py +225 -0
  6. package/runtime/python/okstra_ctl/resolve_task_key.py +15 -9
  7. package/runtime/python/okstra_ctl/session.py +44 -0
  8. package/runtime/python/okstra_project/__init__.py +2 -0
  9. package/runtime/python/okstra_project/state.py +36 -0
  10. package/runtime/python/okstra_token_usage/claude.py +15 -9
  11. package/runtime/python/okstra_token_usage/cli.py +23 -0
  12. package/runtime/python/okstra_token_usage/collect.py +163 -4
  13. package/runtime/python/okstra_vendor/__init__.py +41 -0
  14. package/runtime/python/okstra_vendor/graphify/.vendored-version +1 -0
  15. package/runtime/python/okstra_vendor/graphify/__init__.py +28 -0
  16. package/runtime/python/okstra_vendor/graphify/__main__.py +1371 -0
  17. package/runtime/python/okstra_vendor/graphify/analyze.py +540 -0
  18. package/runtime/python/okstra_vendor/graphify/benchmark.py +129 -0
  19. package/runtime/python/okstra_vendor/graphify/build.py +107 -0
  20. package/runtime/python/okstra_vendor/graphify/cache.py +169 -0
  21. package/runtime/python/okstra_vendor/graphify/cluster.py +137 -0
  22. package/runtime/python/okstra_vendor/graphify/detect.py +510 -0
  23. package/runtime/python/okstra_vendor/graphify/export.py +1014 -0
  24. package/runtime/python/okstra_vendor/graphify/extract.py +3277 -0
  25. package/runtime/python/okstra_vendor/graphify/hooks.py +220 -0
  26. package/runtime/python/okstra_vendor/graphify/ingest.py +297 -0
  27. package/runtime/python/okstra_vendor/graphify/manifest.py +4 -0
  28. package/runtime/python/okstra_vendor/graphify/report.py +175 -0
  29. package/runtime/python/okstra_vendor/graphify/security.py +203 -0
  30. package/runtime/python/okstra_vendor/graphify/serve.py +373 -0
  31. package/runtime/python/okstra_vendor/graphify/skill-aider.md +1184 -0
  32. package/runtime/python/okstra_vendor/graphify/skill-claw.md +1184 -0
  33. package/runtime/python/okstra_vendor/graphify/skill-codex.md +1242 -0
  34. package/runtime/python/okstra_vendor/graphify/skill-copilot.md +1268 -0
  35. package/runtime/python/okstra_vendor/graphify/skill-droid.md +1239 -0
  36. package/runtime/python/okstra_vendor/graphify/skill-kiro.md +1183 -0
  37. package/runtime/python/okstra_vendor/graphify/skill-opencode.md +1238 -0
  38. package/runtime/python/okstra_vendor/graphify/skill-trae.md +1208 -0
  39. package/runtime/python/okstra_vendor/graphify/skill-vscode.md +253 -0
  40. package/runtime/python/okstra_vendor/graphify/skill-windows.md +1245 -0
  41. package/runtime/python/okstra_vendor/graphify/skill.md +1319 -0
  42. package/runtime/python/okstra_vendor/graphify/transcribe.py +182 -0
  43. package/runtime/python/okstra_vendor/graphify/validate.py +72 -0
  44. package/runtime/python/okstra_vendor/graphify/watch.py +188 -0
  45. package/runtime/python/okstra_vendor/graphify/wiki.py +214 -0
  46. package/runtime/python/okstra_vendor/networkx/__init__.py +62 -0
  47. package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +134 -0
  48. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +26 -0
  49. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +259 -0
  50. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +71 -0
  51. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +412 -0
  52. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +396 -0
  53. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +150 -0
  54. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +149 -0
  55. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +369 -0
  56. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +44 -0
  57. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +143 -0
  58. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +53 -0
  59. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +265 -0
  60. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/__init__.py +0 -0
  61. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_approx_clust_coeff.py +41 -0
  62. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_clique.py +112 -0
  63. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_connectivity.py +199 -0
  64. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_density.py +146 -0
  65. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_distance_measures.py +59 -0
  66. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_dominating_set.py +78 -0
  67. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_kcomponents.py +303 -0
  68. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_matching.py +8 -0
  69. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_maxcut.py +94 -0
  70. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_ramsey.py +31 -0
  71. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_steinertree.py +306 -0
  72. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_traveling_salesman.py +1014 -0
  73. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_treewidth.py +274 -0
  74. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_vertex_cover.py +68 -0
  75. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +1508 -0
  76. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +255 -0
  77. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +83 -0
  78. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +5 -0
  79. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +122 -0
  80. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +302 -0
  81. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +255 -0
  82. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +160 -0
  83. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +127 -0
  84. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/__init__.py +0 -0
  85. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/base_test.py +81 -0
  86. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_connectivity.py +143 -0
  87. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_correlation.py +122 -0
  88. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_mixing.py +174 -0
  89. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_neighbor_degree.py +107 -0
  90. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_pairs.py +87 -0
  91. package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +164 -0
  92. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +88 -0
  93. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +322 -0
  94. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +290 -0
  95. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +289 -0
  96. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +57 -0
  97. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +360 -0
  98. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +105 -0
  99. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +603 -0
  100. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +316 -0
  101. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +590 -0
  102. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +232 -0
  103. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +526 -0
  104. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +112 -0
  105. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +69 -0
  106. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/__init__.py +0 -0
  107. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_basic.py +125 -0
  108. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_centrality.py +192 -0
  109. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_cluster.py +84 -0
  110. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_covering.py +33 -0
  111. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_edgelist.py +240 -0
  112. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_extendability.py +334 -0
  113. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_generators.py +407 -0
  114. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_link_analysis.py +218 -0
  115. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matching.py +327 -0
  116. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matrix.py +138 -0
  117. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_project.py +409 -0
  118. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_redundancy.py +35 -0
  119. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_spectral_bipartivity.py +80 -0
  120. package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +168 -0
  121. package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +205 -0
  122. package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +164 -0
  123. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +20 -0
  124. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +591 -0
  125. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +236 -0
  126. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +282 -0
  127. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +364 -0
  128. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +227 -0
  129. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +96 -0
  130. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +150 -0
  131. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +107 -0
  132. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +357 -0
  133. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +130 -0
  134. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +787 -0
  135. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +88 -0
  136. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +331 -0
  137. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +150 -0
  138. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +200 -0
  139. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +128 -0
  140. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +209 -0
  141. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +141 -0
  142. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +361 -0
  143. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/__init__.py +0 -0
  144. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality.py +923 -0
  145. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality_subset.py +354 -0
  146. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_closeness_centrality.py +274 -0
  147. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality.py +259 -0
  148. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality_subset.py +147 -0
  149. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_closeness.py +43 -0
  150. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_degree_centrality.py +144 -0
  151. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_dispersion.py +73 -0
  152. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_eigenvector_centrality.py +186 -0
  153. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_group.py +277 -0
  154. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_harmonic_centrality.py +122 -0
  155. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_katz_centrality.py +345 -0
  156. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_laplacian_centrality.py +220 -0
  157. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_load_centrality.py +344 -0
  158. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_percolation_centrality.py +87 -0
  159. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_reaching.py +140 -0
  160. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_second_order_centrality.py +82 -0
  161. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_subgraph.py +110 -0
  162. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_trophic.py +302 -0
  163. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_voterank.py +64 -0
  164. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +181 -0
  165. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +95 -0
  166. package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +172 -0
  167. package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +443 -0
  168. package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +818 -0
  169. package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +732 -0
  170. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +4 -0
  171. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +505 -0
  172. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +565 -0
  173. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/__init__.py +0 -0
  174. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/test_coloring.py +863 -0
  175. package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +163 -0
  176. package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +28 -0
  177. package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +153 -0
  178. package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +354 -0
  179. package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +171 -0
  180. package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +30 -0
  181. package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +216 -0
  182. package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +79 -0
  183. package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +338 -0
  184. package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +162 -0
  185. package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +220 -0
  186. package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +384 -0
  187. package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +227 -0
  188. package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +452 -0
  189. package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +347 -0
  190. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/__init__.py +0 -0
  191. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_asyn_fluid.py +147 -0
  192. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_bipartitions.py +157 -0
  193. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_centrality.py +85 -0
  194. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_divisive.py +106 -0
  195. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_kclique.py +91 -0
  196. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_label_propagation.py +241 -0
  197. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_leiden.py +138 -0
  198. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_local.py +76 -0
  199. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_louvain.py +264 -0
  200. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_lukes.py +152 -0
  201. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_modularity_max.py +340 -0
  202. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_quality.py +139 -0
  203. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_utils.py +26 -0
  204. package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +6 -0
  205. package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +115 -0
  206. package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +394 -0
  207. package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +282 -0
  208. package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +71 -0
  209. package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +359 -0
  210. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/__init__.py +0 -0
  211. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_attracting.py +70 -0
  212. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_biconnected.py +248 -0
  213. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_connected.py +138 -0
  214. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_semiconnected.py +55 -0
  215. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_strongly_connected.py +193 -0
  216. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_weakly_connected.py +96 -0
  217. package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +196 -0
  218. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +11 -0
  219. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +811 -0
  220. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +616 -0
  221. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +408 -0
  222. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +1270 -0
  223. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +592 -0
  224. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +220 -0
  225. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +235 -0
  226. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +152 -0
  227. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/__init__.py +0 -0
  228. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_connectivity.py +421 -0
  229. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_cuts.py +309 -0
  230. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_disjoint_paths.py +249 -0
  231. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_augmentation.py +502 -0
  232. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_kcomponents.py +488 -0
  233. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcomponents.py +323 -0
  234. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcutsets.py +280 -0
  235. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_stoer_wagner.py +102 -0
  236. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +88 -0
  237. package/runtime/python/okstra_vendor/networkx/algorithms/core.py +588 -0
  238. package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +142 -0
  239. package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +416 -0
  240. package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +1234 -0
  241. package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +677 -0
  242. package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +1392 -0
  243. package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +1095 -0
  244. package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +272 -0
  245. package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +142 -0
  246. package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +268 -0
  247. package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +167 -0
  248. package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +470 -0
  249. package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +11 -0
  250. package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +370 -0
  251. package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +407 -0
  252. package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +238 -0
  253. package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +241 -0
  254. package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +178 -0
  255. package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +611 -0
  256. package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +356 -0
  257. package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +662 -0
  258. package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +425 -0
  259. package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +300 -0
  260. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/__init__.py +0 -0
  261. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gl1.gpickle.bz2 +0 -0
  262. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gw1.gpickle.bz2 +0 -0
  263. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/netgen-2.gpickle.bz2 +0 -0
  264. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_gomory_hu.py +128 -0
  265. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow.py +573 -0
  266. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow_large_graph.py +155 -0
  267. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_mincost.py +475 -0
  268. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_networksimplex.py +481 -0
  269. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/wlm3.gpickle.bz2 +0 -0
  270. package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +194 -0
  271. package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +435 -0
  272. package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +483 -0
  273. package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +57 -0
  274. package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +196 -0
  275. package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +107 -0
  276. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +7 -0
  277. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +1306 -0
  278. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +336 -0
  279. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +1262 -0
  280. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +352 -0
  281. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +308 -0
  282. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/__init__.py +0 -0
  283. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.A99 +0 -0
  284. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.B99 +0 -0
  285. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.A99 +0 -0
  286. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.B99 +0 -0
  287. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_ismags.py +719 -0
  288. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphism.py +103 -0
  289. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphvf2.py +490 -0
  290. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_match_helpers.py +64 -0
  291. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_temporalisomorphvf2.py +212 -0
  292. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_tree_isomorphism.py +202 -0
  293. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp.py +1655 -0
  294. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp_helpers.py +3118 -0
  295. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2userfunc.py +196 -0
  296. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +264 -0
  297. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +1102 -0
  298. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +192 -0
  299. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +2 -0
  300. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +337 -0
  301. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +498 -0
  302. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/__init__.py +0 -0
  303. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_hits.py +77 -0
  304. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_pagerank.py +213 -0
  305. package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +687 -0
  306. package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +280 -0
  307. package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +1148 -0
  308. package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +27 -0
  309. package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +738 -0
  310. package/runtime/python/okstra_vendor/networkx/algorithms/minors/tests/test_contraction.py +544 -0
  311. package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +78 -0
  312. package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +59 -0
  313. package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +219 -0
  314. package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +155 -0
  315. package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +4 -0
  316. package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +324 -0
  317. package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +468 -0
  318. package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +633 -0
  319. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/__init__.py +0 -0
  320. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_all.py +328 -0
  321. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_binary.py +451 -0
  322. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_product.py +491 -0
  323. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_unary.py +55 -0
  324. package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +77 -0
  325. package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +73 -0
  326. package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +464 -0
  327. package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +1463 -0
  328. package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +306 -0
  329. package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +98 -0
  330. package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +167 -0
  331. package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +138 -0
  332. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +5 -0
  333. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +239 -0
  334. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +264 -0
  335. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +716 -0
  336. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/__init__.py +0 -0
  337. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_astar.py +254 -0
  338. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense.py +212 -0
  339. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py +88 -0
  340. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_generic.py +511 -0
  341. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_unweighted.py +149 -0
  342. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_weighted.py +983 -0
  343. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +625 -0
  344. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +2542 -0
  345. package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +2107 -0
  346. package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +966 -0
  347. package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +404 -0
  348. package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +30 -0
  349. package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +296 -0
  350. package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +374 -0
  351. package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +564 -0
  352. package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +406 -0
  353. package/runtime/python/okstra_vendor/networkx/algorithms/tests/__init__.py +0 -0
  354. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_asteroidal.py +23 -0
  355. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_boundary.py +154 -0
  356. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_bridges.py +144 -0
  357. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_broadcasting.py +109 -0
  358. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chains.py +136 -0
  359. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chordal.py +129 -0
  360. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_clique.py +300 -0
  361. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cluster.py +678 -0
  362. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_communicability.py +80 -0
  363. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_core.py +266 -0
  364. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_covering.py +85 -0
  365. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cuts.py +171 -0
  366. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cycles.py +984 -0
  367. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_d_separation.py +340 -0
  368. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dag.py +835 -0
  369. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_measures.py +831 -0
  370. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_regular.py +85 -0
  371. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominance.py +299 -0
  372. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominating.py +115 -0
  373. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_efficiency.py +58 -0
  374. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_euler.py +314 -0
  375. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graph_hashing.py +872 -0
  376. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graphical.py +163 -0
  377. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hierarchy.py +46 -0
  378. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hybrid.py +24 -0
  379. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_isolate.py +26 -0
  380. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_link_prediction.py +615 -0
  381. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_lowest_common_ancestors.py +459 -0
  382. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_matching.py +556 -0
  383. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_max_weight_clique.py +179 -0
  384. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_mis.py +62 -0
  385. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_moral.py +15 -0
  386. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_node_classification.py +140 -0
  387. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_non_randomness.py +60 -0
  388. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_perfect_graph.py +27 -0
  389. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planar_drawing.py +274 -0
  390. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planarity.py +556 -0
  391. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_polynomials.py +57 -0
  392. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_reciprocity.py +37 -0
  393. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_regular.py +88 -0
  394. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_richclub.py +149 -0
  395. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_similarity.py +1158 -0
  396. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_simple_paths.py +803 -0
  397. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smallworld.py +76 -0
  398. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smetric.py +8 -0
  399. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_sparsifiers.py +138 -0
  400. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_structuralholes.py +191 -0
  401. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_summarization.py +642 -0
  402. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_swap.py +179 -0
  403. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_threshold.py +270 -0
  404. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_time_dependent.py +431 -0
  405. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_tournament.py +161 -0
  406. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_triads.py +248 -0
  407. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_vitality.py +41 -0
  408. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_voronoi.py +103 -0
  409. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_walks.py +54 -0
  410. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_wiener.py +157 -0
  411. package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +981 -0
  412. package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +142 -0
  413. package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +406 -0
  414. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +5 -0
  415. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +90 -0
  416. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +576 -0
  417. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +529 -0
  418. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +185 -0
  419. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +182 -0
  420. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/__init__.py +0 -0
  421. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_beamsearch.py +25 -0
  422. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_bfs.py +203 -0
  423. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_dfs.py +307 -0
  424. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgebfs.py +147 -0
  425. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgedfs.py +131 -0
  426. package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +7 -0
  427. package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +1042 -0
  428. package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +413 -0
  429. package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +88 -0
  430. package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +219 -0
  431. package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +1281 -0
  432. package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +106 -0
  433. package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +273 -0
  434. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/__init__.py +0 -0
  435. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_branchings.py +624 -0
  436. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_coding.py +114 -0
  437. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_decomposition.py +79 -0
  438. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_distance_measures.py +99 -0
  439. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_mst.py +934 -0
  440. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_operations.py +53 -0
  441. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_recognition.py +174 -0
  442. package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +500 -0
  443. package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +76 -0
  444. package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +86 -0
  445. package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +77 -0
  446. package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +278 -0
  447. package/runtime/python/okstra_vendor/networkx/classes/__init__.py +13 -0
  448. package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +435 -0
  449. package/runtime/python/okstra_vendor/networkx/classes/digraph.py +1363 -0
  450. package/runtime/python/okstra_vendor/networkx/classes/filters.py +95 -0
  451. package/runtime/python/okstra_vendor/networkx/classes/function.py +1549 -0
  452. package/runtime/python/okstra_vendor/networkx/classes/graph.py +2082 -0
  453. package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +269 -0
  454. package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +977 -0
  455. package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +1294 -0
  456. package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +1447 -0
  457. package/runtime/python/okstra_vendor/networkx/classes/tests/__init__.py +0 -0
  458. package/runtime/python/okstra_vendor/networkx/classes/tests/dispatch_interface.py +192 -0
  459. package/runtime/python/okstra_vendor/networkx/classes/tests/historical_tests.py +476 -0
  460. package/runtime/python/okstra_vendor/networkx/classes/tests/test_coreviews.py +362 -0
  461. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph.py +331 -0
  462. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph_historical.py +110 -0
  463. package/runtime/python/okstra_vendor/networkx/classes/tests/test_filters.py +177 -0
  464. package/runtime/python/okstra_vendor/networkx/classes/tests/test_function.py +1045 -0
  465. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph.py +950 -0
  466. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph_historical.py +12 -0
  467. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graphviews.py +349 -0
  468. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multidigraph.py +459 -0
  469. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multigraph.py +528 -0
  470. package/runtime/python/okstra_vendor/networkx/classes/tests/test_reportviews.py +1421 -0
  471. package/runtime/python/okstra_vendor/networkx/classes/tests/test_special.py +131 -0
  472. package/runtime/python/okstra_vendor/networkx/classes/tests/test_subgraphviews.py +371 -0
  473. package/runtime/python/okstra_vendor/networkx/conftest.py +261 -0
  474. package/runtime/python/okstra_vendor/networkx/convert.py +502 -0
  475. package/runtime/python/okstra_vendor/networkx/convert_matrix.py +1314 -0
  476. package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +7 -0
  477. package/runtime/python/okstra_vendor/networkx/drawing/layout.py +2036 -0
  478. package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +470 -0
  479. package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +570 -0
  480. package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +361 -0
  481. package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +2978 -0
  482. package/runtime/python/okstra_vendor/networkx/drawing/tests/__init__.py +0 -0
  483. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_complex.png +0 -0
  484. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_empty_graph.png +0 -0
  485. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_house_with_colors.png +0 -0
  486. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_labels_and_colors.png +0 -0
  487. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_shortest_path.png +0 -0
  488. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_house_with_colors.png +0 -0
  489. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_agraph.py +237 -0
  490. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_image_comparison_pylab_mpl.py +229 -0
  491. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_latex.py +285 -0
  492. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_layout.py +631 -0
  493. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pydot.py +146 -0
  494. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pylab.py +1582 -0
  495. package/runtime/python/okstra_vendor/networkx/exception.py +131 -0
  496. package/runtime/python/okstra_vendor/networkx/generators/__init__.py +34 -0
  497. package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
  498. package/runtime/python/okstra_vendor/networkx/generators/atlas.py +227 -0
  499. package/runtime/python/okstra_vendor/networkx/generators/classic.py +1091 -0
  500. package/runtime/python/okstra_vendor/networkx/generators/cographs.py +68 -0
  501. package/runtime/python/okstra_vendor/networkx/generators/community.py +1070 -0
  502. package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +886 -0
  503. package/runtime/python/okstra_vendor/networkx/generators/directed.py +572 -0
  504. package/runtime/python/okstra_vendor/networkx/generators/duplication.py +174 -0
  505. package/runtime/python/okstra_vendor/networkx/generators/ego.py +66 -0
  506. package/runtime/python/okstra_vendor/networkx/generators/expanders.py +499 -0
  507. package/runtime/python/okstra_vendor/networkx/generators/geometric.py +1037 -0
  508. package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +163 -0
  509. package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +443 -0
  510. package/runtime/python/okstra_vendor/networkx/generators/intersection.py +125 -0
  511. package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +70 -0
  512. package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +664 -0
  513. package/runtime/python/okstra_vendor/networkx/generators/lattice.py +405 -0
  514. package/runtime/python/okstra_vendor/networkx/generators/line.py +501 -0
  515. package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +110 -0
  516. package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +259 -0
  517. package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +117 -0
  518. package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +1416 -0
  519. package/runtime/python/okstra_vendor/networkx/generators/small.py +1070 -0
  520. package/runtime/python/okstra_vendor/networkx/generators/social.py +554 -0
  521. package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +120 -0
  522. package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +54 -0
  523. package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +131 -0
  524. package/runtime/python/okstra_vendor/networkx/generators/tests/__init__.py +0 -0
  525. package/runtime/python/okstra_vendor/networkx/generators/tests/test_atlas.py +75 -0
  526. package/runtime/python/okstra_vendor/networkx/generators/tests/test_classic.py +642 -0
  527. package/runtime/python/okstra_vendor/networkx/generators/tests/test_cographs.py +20 -0
  528. package/runtime/python/okstra_vendor/networkx/generators/tests/test_community.py +362 -0
  529. package/runtime/python/okstra_vendor/networkx/generators/tests/test_degree_seq.py +224 -0
  530. package/runtime/python/okstra_vendor/networkx/generators/tests/test_directed.py +189 -0
  531. package/runtime/python/okstra_vendor/networkx/generators/tests/test_duplication.py +103 -0
  532. package/runtime/python/okstra_vendor/networkx/generators/tests/test_ego.py +39 -0
  533. package/runtime/python/okstra_vendor/networkx/generators/tests/test_expanders.py +182 -0
  534. package/runtime/python/okstra_vendor/networkx/generators/tests/test_geometric.py +488 -0
  535. package/runtime/python/okstra_vendor/networkx/generators/tests/test_harary_graph.py +133 -0
  536. package/runtime/python/okstra_vendor/networkx/generators/tests/test_internet_as_graphs.py +221 -0
  537. package/runtime/python/okstra_vendor/networkx/generators/tests/test_intersection.py +28 -0
  538. package/runtime/python/okstra_vendor/networkx/generators/tests/test_interval_graph.py +144 -0
  539. package/runtime/python/okstra_vendor/networkx/generators/tests/test_joint_degree_seq.py +125 -0
  540. package/runtime/python/okstra_vendor/networkx/generators/tests/test_lattice.py +264 -0
  541. package/runtime/python/okstra_vendor/networkx/generators/tests/test_line.py +316 -0
  542. package/runtime/python/okstra_vendor/networkx/generators/tests/test_mycielski.py +30 -0
  543. package/runtime/python/okstra_vendor/networkx/generators/tests/test_nonisomorphic_trees.py +82 -0
  544. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_clustered.py +33 -0
  545. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_graphs.py +495 -0
  546. package/runtime/python/okstra_vendor/networkx/generators/tests/test_small.py +220 -0
  547. package/runtime/python/okstra_vendor/networkx/generators/tests/test_spectral_graph_forge.py +49 -0
  548. package/runtime/python/okstra_vendor/networkx/generators/tests/test_stochastic.py +72 -0
  549. package/runtime/python/okstra_vendor/networkx/generators/tests/test_sudoku.py +92 -0
  550. package/runtime/python/okstra_vendor/networkx/generators/tests/test_time_series.py +64 -0
  551. package/runtime/python/okstra_vendor/networkx/generators/tests/test_trees.py +195 -0
  552. package/runtime/python/okstra_vendor/networkx/generators/tests/test_triads.py +15 -0
  553. package/runtime/python/okstra_vendor/networkx/generators/time_series.py +74 -0
  554. package/runtime/python/okstra_vendor/networkx/generators/trees.py +1070 -0
  555. package/runtime/python/okstra_vendor/networkx/generators/triads.py +94 -0
  556. package/runtime/python/okstra_vendor/networkx/lazy_imports.py +188 -0
  557. package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +13 -0
  558. package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +650 -0
  559. package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +466 -0
  560. package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +77 -0
  561. package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +168 -0
  562. package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +512 -0
  563. package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +166 -0
  564. package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +186 -0
  565. package/runtime/python/okstra_vendor/networkx/linalg/tests/__init__.py +0 -0
  566. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_algebraic_connectivity.py +400 -0
  567. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_attrmatrix.py +108 -0
  568. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_bethehessian.py +40 -0
  569. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_graphmatrix.py +275 -0
  570. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_laplacian.py +334 -0
  571. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_modularity.py +86 -0
  572. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_spectrum.py +70 -0
  573. package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +17 -0
  574. package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +330 -0
  575. package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +489 -0
  576. package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +1084 -0
  577. package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +879 -0
  578. package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +427 -0
  579. package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +1053 -0
  580. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +19 -0
  581. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +156 -0
  582. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +190 -0
  583. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +261 -0
  584. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/__init__.py +0 -0
  585. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_adjacency.py +78 -0
  586. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_cytoscape.py +78 -0
  587. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_node_link.py +109 -0
  588. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_tree.py +48 -0
  589. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +137 -0
  590. package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +108 -0
  591. package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +393 -0
  592. package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +113 -0
  593. package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +286 -0
  594. package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +379 -0
  595. package/runtime/python/okstra_vendor/networkx/readwrite/tests/__init__.py +0 -0
  596. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_adjlist.py +354 -0
  597. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_edgelist.py +318 -0
  598. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gexf.py +612 -0
  599. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gml.py +744 -0
  600. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graph6.py +181 -0
  601. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graphml.py +1531 -0
  602. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_leda.py +30 -0
  603. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_p2g.py +63 -0
  604. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_pajek.py +128 -0
  605. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_sparse6.py +166 -0
  606. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_text.py +1742 -0
  607. package/runtime/python/okstra_vendor/networkx/readwrite/text.py +851 -0
  608. package/runtime/python/okstra_vendor/networkx/relabel.py +285 -0
  609. package/runtime/python/okstra_vendor/networkx/tests/__init__.py +0 -0
  610. package/runtime/python/okstra_vendor/networkx/tests/test_all_random_functions.py +248 -0
  611. package/runtime/python/okstra_vendor/networkx/tests/test_convert.py +321 -0
  612. package/runtime/python/okstra_vendor/networkx/tests/test_convert_numpy.py +531 -0
  613. package/runtime/python/okstra_vendor/networkx/tests/test_convert_pandas.py +349 -0
  614. package/runtime/python/okstra_vendor/networkx/tests/test_convert_scipy.py +281 -0
  615. package/runtime/python/okstra_vendor/networkx/tests/test_exceptions.py +40 -0
  616. package/runtime/python/okstra_vendor/networkx/tests/test_import.py +11 -0
  617. package/runtime/python/okstra_vendor/networkx/tests/test_lazy_imports.py +96 -0
  618. package/runtime/python/okstra_vendor/networkx/tests/test_relabel.py +349 -0
  619. package/runtime/python/okstra_vendor/networkx/tests/test_removed_functions_exception_messages.py +8 -0
  620. package/runtime/python/okstra_vendor/networkx/utils/__init__.py +8 -0
  621. package/runtime/python/okstra_vendor/networkx/utils/backends.py +2171 -0
  622. package/runtime/python/okstra_vendor/networkx/utils/configs.py +396 -0
  623. package/runtime/python/okstra_vendor/networkx/utils/decorators.py +1233 -0
  624. package/runtime/python/okstra_vendor/networkx/utils/heaps.py +338 -0
  625. package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +297 -0
  626. package/runtime/python/okstra_vendor/networkx/utils/misc.py +703 -0
  627. package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +198 -0
  628. package/runtime/python/okstra_vendor/networkx/utils/rcm.py +159 -0
  629. package/runtime/python/okstra_vendor/networkx/utils/tests/__init__.py +0 -0
  630. package/runtime/python/okstra_vendor/networkx/utils/tests/test__init.py +11 -0
  631. package/runtime/python/okstra_vendor/networkx/utils/tests/test_backends.py +225 -0
  632. package/runtime/python/okstra_vendor/networkx/utils/tests/test_config.py +263 -0
  633. package/runtime/python/okstra_vendor/networkx/utils/tests/test_decorators.py +510 -0
  634. package/runtime/python/okstra_vendor/networkx/utils/tests/test_heaps.py +131 -0
  635. package/runtime/python/okstra_vendor/networkx/utils/tests/test_mapped_queue.py +268 -0
  636. package/runtime/python/okstra_vendor/networkx/utils/tests/test_misc.py +393 -0
  637. package/runtime/python/okstra_vendor/networkx/utils/tests/test_random_sequence.py +53 -0
  638. package/runtime/python/okstra_vendor/networkx/utils/tests/test_rcm.py +63 -0
  639. package/runtime/python/okstra_vendor/networkx/utils/tests/test_unionfind.py +55 -0
  640. package/runtime/python/okstra_vendor/networkx/utils/union_find.py +106 -0
  641. package/runtime/skills/okstra-graphify/SKILL.md +161 -0
  642. package/runtime/skills/okstra-inspect/SKILL.md +17 -9
  643. package/runtime/templates/reports/settings.template.json +4 -0
  644. package/runtime/validators/forbidden_actions.py +8 -2
  645. package/runtime/validators/validate_session_conformance.py +26 -5
  646. package/src/cli-registry.mjs +7 -0
  647. package/src/commands/graphify.mjs +32 -0
  648. package/src/commands/lifecycle/doctor.mjs +9 -0
  649. package/src/lib/skill-catalog.mjs +1 -0
@@ -0,0 +1,1314 @@
1
+ """Functions to convert NetworkX graphs to and from common data containers
2
+ like numpy arrays, scipy sparse arrays, and pandas DataFrames.
3
+
4
+ The preferred way of converting data to a NetworkX graph is through the
5
+ graph constructor. The constructor calls the `~networkx.convert.to_networkx_graph`
6
+ function which attempts to guess the input type and convert it automatically.
7
+
8
+ Examples
9
+ --------
10
+ Create a 10 node random graph from a numpy array
11
+
12
+ >>> import numpy as np
13
+ >>> rng = np.random.default_rng()
14
+ >>> a = rng.integers(low=0, high=2, size=(10, 10))
15
+ >>> DG = nx.from_numpy_array(a, create_using=nx.DiGraph)
16
+
17
+ or equivalently:
18
+
19
+ >>> DG = nx.DiGraph(a)
20
+
21
+ which calls `from_numpy_array` internally based on the type of ``a``.
22
+
23
+ See Also
24
+ --------
25
+ nx_agraph, nx_pydot
26
+ """
27
+
28
+ import itertools
29
+ from collections import defaultdict
30
+
31
+ import networkx as nx
32
+
33
+ __all__ = [
34
+ "from_pandas_adjacency",
35
+ "to_pandas_adjacency",
36
+ "from_pandas_edgelist",
37
+ "to_pandas_edgelist",
38
+ "from_scipy_sparse_array",
39
+ "to_scipy_sparse_array",
40
+ "from_numpy_array",
41
+ "to_numpy_array",
42
+ ]
43
+
44
+
45
+ @nx._dispatchable(edge_attrs="weight")
46
+ def to_pandas_adjacency(
47
+ G,
48
+ nodelist=None,
49
+ dtype=None,
50
+ order=None,
51
+ multigraph_weight=sum,
52
+ weight="weight",
53
+ nonedge=0.0,
54
+ ):
55
+ """Returns the graph adjacency matrix as a Pandas DataFrame.
56
+
57
+ Parameters
58
+ ----------
59
+ G : graph
60
+ The NetworkX graph used to construct the Pandas DataFrame.
61
+
62
+ nodelist : list, optional
63
+ The rows and columns are ordered according to the nodes in `nodelist`.
64
+ If `nodelist` is None, then the ordering is produced by G.nodes().
65
+
66
+ multigraph_weight : {sum, min, max}, optional
67
+ An operator that determines how weights in multigraphs are handled.
68
+ The default is to sum the weights of the multiple edges.
69
+
70
+ weight : string or None, optional
71
+ The edge attribute that holds the numerical value used for
72
+ the edge weight. If an edge does not have that attribute, then the
73
+ value 1 is used instead.
74
+
75
+ nonedge : float, optional
76
+ The matrix values corresponding to nonedges are typically set to zero.
77
+ However, this could be undesirable if there are matrix values
78
+ corresponding to actual edges that also have the value zero. If so,
79
+ one might prefer nonedges to have some other value, such as nan.
80
+
81
+ Returns
82
+ -------
83
+ df : Pandas DataFrame
84
+ Graph adjacency matrix
85
+
86
+ Notes
87
+ -----
88
+ For directed graphs, entry i,j corresponds to an edge from i to j.
89
+
90
+ The DataFrame entries are assigned to the weight edge attribute. When
91
+ an edge does not have a weight attribute, the value of the entry is set to
92
+ the number 1. For multiple (parallel) edges, the values of the entries
93
+ are determined by the 'multigraph_weight' parameter. The default is to
94
+ sum the weight attributes for each of the parallel edges.
95
+
96
+ When `nodelist` does not contain every node in `G`, the matrix is built
97
+ from the subgraph of `G` that is induced by the nodes in `nodelist`.
98
+
99
+ The convention used for self-loop edges in graphs is to assign the
100
+ diagonal matrix entry value to the weight attribute of the edge
101
+ (or the number 1 if the edge has no weight attribute). If the
102
+ alternate convention of doubling the edge weight is desired the
103
+ resulting Pandas DataFrame can be modified as follows::
104
+
105
+ >>> import pandas as pd
106
+ >>> G = nx.Graph([(1, 1), (2, 2)])
107
+ >>> df = nx.to_pandas_adjacency(G)
108
+ >>> df
109
+ 1 2
110
+ 1 1.0 0.0
111
+ 2 0.0 1.0
112
+ >>> diag_idx = list(range(len(df)))
113
+ >>> df.iloc[diag_idx, diag_idx] *= 2
114
+ >>> df
115
+ 1 2
116
+ 1 2.0 0.0
117
+ 2 0.0 2.0
118
+
119
+ Examples
120
+ --------
121
+ >>> G = nx.MultiDiGraph()
122
+ >>> G.add_edge(0, 1, weight=2)
123
+ 0
124
+ >>> G.add_edge(1, 0)
125
+ 0
126
+ >>> G.add_edge(2, 2, weight=3)
127
+ 0
128
+ >>> G.add_edge(2, 2)
129
+ 1
130
+ >>> nx.to_pandas_adjacency(G, nodelist=[0, 1, 2], dtype=int)
131
+ 0 1 2
132
+ 0 0 2 0
133
+ 1 1 0 0
134
+ 2 0 0 4
135
+
136
+ """
137
+ import pandas as pd
138
+
139
+ M = to_numpy_array(
140
+ G,
141
+ nodelist=nodelist,
142
+ dtype=dtype,
143
+ order=order,
144
+ multigraph_weight=multigraph_weight,
145
+ weight=weight,
146
+ nonedge=nonedge,
147
+ )
148
+ if nodelist is None:
149
+ nodelist = list(G)
150
+ return pd.DataFrame(data=M, index=nodelist, columns=nodelist)
151
+
152
+
153
+ @nx._dispatchable(graphs=None, returns_graph=True)
154
+ def from_pandas_adjacency(df, create_using=None):
155
+ r"""Returns a graph from Pandas DataFrame.
156
+
157
+ The Pandas DataFrame is interpreted as an adjacency matrix for the graph.
158
+
159
+ Parameters
160
+ ----------
161
+ df : Pandas DataFrame
162
+ An adjacency matrix representation of a graph
163
+
164
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
165
+ Graph type to create. If graph instance, then cleared before populated.
166
+
167
+ Notes
168
+ -----
169
+ For directed graphs, explicitly mention create_using=nx.DiGraph,
170
+ and entry i,j of df corresponds to an edge from i to j.
171
+
172
+ If `df` has a single data type for each entry it will be converted to an
173
+ appropriate Python data type.
174
+
175
+ If you have node attributes stored in a separate dataframe `df_nodes`,
176
+ you can load those attributes to the graph `G` using the following code::
177
+
178
+ df_nodes = pd.DataFrame({"node_id": [1, 2, 3], "attribute1": ["A", "B", "C"]})
179
+ G.add_nodes_from((n, dict(d)) for n, d in df_nodes.iterrows())
180
+
181
+ If `df` has a user-specified compound data type the names
182
+ of the data fields will be used as attribute keys in the resulting
183
+ NetworkX graph.
184
+
185
+ See Also
186
+ --------
187
+ to_pandas_adjacency
188
+
189
+ Examples
190
+ --------
191
+ Simple integer weights on edges:
192
+
193
+ >>> import pandas as pd
194
+ >>> pd.options.display.max_columns = 20
195
+ >>> df = pd.DataFrame([[1, 1], [2, 1]])
196
+ >>> df
197
+ 0 1
198
+ 0 1 1
199
+ 1 2 1
200
+ >>> G = nx.from_pandas_adjacency(df)
201
+ >>> G.name = "Graph from pandas adjacency matrix"
202
+ >>> print(G)
203
+ Graph named 'Graph from pandas adjacency matrix' with 2 nodes and 3 edges
204
+ """
205
+
206
+ try:
207
+ df = df[df.index]
208
+ except Exception as err:
209
+ missing = list(set(df.index).difference(set(df.columns)))
210
+ msg = f"{missing} not in columns"
211
+ raise nx.NetworkXError("Columns must match Indices.", msg) from err
212
+
213
+ A = df.values
214
+ G = from_numpy_array(A, create_using=create_using, nodelist=df.columns)
215
+
216
+ return G
217
+
218
+
219
+ @nx._dispatchable(preserve_edge_attrs=True)
220
+ def to_pandas_edgelist(
221
+ G,
222
+ source="source",
223
+ target="target",
224
+ nodelist=None,
225
+ dtype=None,
226
+ edge_key=None,
227
+ ):
228
+ """Returns the graph edge list as a Pandas DataFrame.
229
+
230
+ Parameters
231
+ ----------
232
+ G : graph
233
+ The NetworkX graph used to construct the Pandas DataFrame.
234
+
235
+ source : str or int, optional
236
+ A valid column name (string or integer) for the source nodes (for the
237
+ directed case).
238
+
239
+ target : str or int, optional
240
+ A valid column name (string or integer) for the target nodes (for the
241
+ directed case).
242
+
243
+ nodelist : list, optional
244
+ Use only nodes specified in nodelist
245
+
246
+ dtype : dtype, default None
247
+ Use to create the DataFrame. Data type to force.
248
+ Only a single dtype is allowed. If None, infer.
249
+
250
+ edge_key : str or int or None, optional (default=None)
251
+ A valid column name (string or integer) for the edge keys (for the
252
+ multigraph case). If None, edge keys are not stored in the DataFrame.
253
+
254
+ Returns
255
+ -------
256
+ df : Pandas DataFrame
257
+ Graph edge list
258
+
259
+ Examples
260
+ --------
261
+ >>> G = nx.Graph(
262
+ ... [
263
+ ... ("A", "B", {"cost": 1, "weight": 7}),
264
+ ... ("C", "E", {"cost": 9, "weight": 10}),
265
+ ... ]
266
+ ... )
267
+ >>> df = nx.to_pandas_edgelist(G, nodelist=["A", "C"])
268
+ >>> df[["source", "target", "cost", "weight"]]
269
+ source target cost weight
270
+ 0 A B 1 7
271
+ 1 C E 9 10
272
+
273
+ >>> G = nx.MultiGraph([("A", "B", {"cost": 1}), ("A", "B", {"cost": 9})])
274
+ >>> df = nx.to_pandas_edgelist(G, nodelist=["A", "C"], edge_key="ekey")
275
+ >>> df[["source", "target", "cost", "ekey"]]
276
+ source target cost ekey
277
+ 0 A B 1 0
278
+ 1 A B 9 1
279
+
280
+ """
281
+ import pandas as pd
282
+
283
+ if nodelist is None:
284
+ edgelist = G.edges(data=True)
285
+ else:
286
+ edgelist = G.edges(nodelist, data=True)
287
+ source_nodes = [s for s, _, _ in edgelist]
288
+ target_nodes = [t for _, t, _ in edgelist]
289
+
290
+ all_attrs = set().union(*(d.keys() for _, _, d in edgelist))
291
+ if source in all_attrs:
292
+ raise nx.NetworkXError(f"Source name {source!r} is an edge attr name")
293
+ if target in all_attrs:
294
+ raise nx.NetworkXError(f"Target name {target!r} is an edge attr name")
295
+
296
+ nan = float("nan")
297
+ edge_attr = {k: [d.get(k, nan) for _, _, d in edgelist] for k in all_attrs}
298
+
299
+ if G.is_multigraph() and edge_key is not None:
300
+ if edge_key in all_attrs:
301
+ raise nx.NetworkXError(f"Edge key name {edge_key!r} is an edge attr name")
302
+ edge_keys = [k for _, _, k in G.edges(keys=True)]
303
+ edgelistdict = {source: source_nodes, target: target_nodes, edge_key: edge_keys}
304
+ else:
305
+ edgelistdict = {source: source_nodes, target: target_nodes}
306
+
307
+ edgelistdict.update(edge_attr)
308
+ return pd.DataFrame(edgelistdict, dtype=dtype)
309
+
310
+
311
+ @nx._dispatchable(graphs=None, returns_graph=True)
312
+ def from_pandas_edgelist(
313
+ df,
314
+ source="source",
315
+ target="target",
316
+ edge_attr=None,
317
+ create_using=None,
318
+ edge_key=None,
319
+ ):
320
+ """Returns a graph from Pandas DataFrame containing an edge list.
321
+
322
+ The Pandas DataFrame should contain at least two columns of node names and
323
+ zero or more columns of edge attributes. Each row will be processed as one
324
+ edge instance.
325
+
326
+ Note: This function iterates over DataFrame.values, which is not
327
+ guaranteed to retain the data type across columns in the row. This is only
328
+ a problem if your row is entirely numeric and a mix of ints and floats. In
329
+ that case, all values will be returned as floats. See the
330
+ DataFrame.iterrows documentation for an example.
331
+
332
+ Parameters
333
+ ----------
334
+ df : Pandas DataFrame
335
+ An edge list representation of a graph
336
+
337
+ source : str or int
338
+ A valid column name (string or integer) for the source nodes (for the
339
+ directed case).
340
+
341
+ target : str or int
342
+ A valid column name (string or integer) for the target nodes (for the
343
+ directed case).
344
+
345
+ edge_attr : str or int, iterable, True, or None
346
+ A valid column name (str or int) or iterable of column names that are
347
+ used to retrieve items and add them to the graph as edge attributes.
348
+ If `True`, all columns will be added except `source`, `target` and `edge_key`.
349
+ If `None`, no edge attributes are added to the graph.
350
+
351
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
352
+ Graph type to create. If graph instance, then cleared before populated.
353
+
354
+ edge_key : str or None, optional (default=None)
355
+ A valid column name for the edge keys (for a MultiGraph). The values in
356
+ this column are used for the edge keys when adding edges if create_using
357
+ is a multigraph.
358
+
359
+ Notes
360
+ -----
361
+ If you have node attributes stored in a separate dataframe `df_nodes`,
362
+ you can load those attributes to the graph `G` using the following code::
363
+
364
+ df_nodes = pd.DataFrame({"node_id": [1, 2, 3], "attribute1": ["A", "B", "C"]})
365
+ G.add_nodes_from((n, dict(d)) for n, d in df_nodes.iterrows())
366
+
367
+ See Also
368
+ --------
369
+ to_pandas_edgelist
370
+
371
+ Examples
372
+ --------
373
+ Simple integer weights on edges:
374
+
375
+ >>> import pandas as pd
376
+ >>> pd.options.display.max_columns = 20
377
+ >>> import numpy as np
378
+ >>> rng = np.random.RandomState(seed=5)
379
+ >>> ints = rng.randint(1, 11, size=(3, 2))
380
+ >>> a = ["A", "B", "C"]
381
+ >>> b = ["D", "A", "E"]
382
+ >>> df = pd.DataFrame(ints, columns=["weight", "cost"])
383
+ >>> df[0] = a
384
+ >>> df["b"] = b
385
+ >>> df[["weight", "cost", 0, "b"]]
386
+ weight cost 0 b
387
+ 0 4 7 A D
388
+ 1 7 1 B A
389
+ 2 10 9 C E
390
+ >>> G = nx.from_pandas_edgelist(df, 0, "b", ["weight", "cost"])
391
+ >>> G["E"]["C"]["weight"]
392
+ 10
393
+ >>> G["E"]["C"]["cost"]
394
+ 9
395
+ >>> edges = pd.DataFrame(
396
+ ... {
397
+ ... "source": [0, 1, 2],
398
+ ... "target": [2, 2, 3],
399
+ ... "weight": [3, 4, 5],
400
+ ... "color": ["red", "blue", "blue"],
401
+ ... }
402
+ ... )
403
+ >>> G = nx.from_pandas_edgelist(edges, edge_attr=True)
404
+ >>> G[0][2]["color"]
405
+ 'red'
406
+
407
+ Build multigraph with custom keys:
408
+
409
+ >>> edges = pd.DataFrame(
410
+ ... {
411
+ ... "source": [0, 1, 2, 0],
412
+ ... "target": [2, 2, 3, 2],
413
+ ... "my_edge_key": ["A", "B", "C", "D"],
414
+ ... "weight": [3, 4, 5, 6],
415
+ ... "color": ["red", "blue", "blue", "blue"],
416
+ ... }
417
+ ... )
418
+ >>> G = nx.from_pandas_edgelist(
419
+ ... edges,
420
+ ... edge_key="my_edge_key",
421
+ ... edge_attr=["weight", "color"],
422
+ ... create_using=nx.MultiGraph(),
423
+ ... )
424
+ >>> G[0][2]
425
+ AtlasView({'A': {'weight': 3, 'color': 'red'}, 'D': {'weight': 6, 'color': 'blue'}})
426
+
427
+
428
+ """
429
+ g = nx.empty_graph(0, create_using)
430
+
431
+ if edge_attr is None:
432
+ if g.is_multigraph() and edge_key is not None:
433
+ for u, v, k in zip(df[source], df[target], df[edge_key]):
434
+ g.add_edge(u, v, k)
435
+ else:
436
+ g.add_edges_from(zip(df[source], df[target]))
437
+ return g
438
+
439
+ reserved_columns = [source, target]
440
+ if g.is_multigraph() and edge_key is not None:
441
+ reserved_columns.append(edge_key)
442
+
443
+ # Additional columns requested
444
+ attr_col_headings = []
445
+ attribute_data = []
446
+ if edge_attr is True:
447
+ attr_col_headings = [c for c in df.columns if c not in reserved_columns]
448
+ elif isinstance(edge_attr, list | tuple):
449
+ attr_col_headings = edge_attr
450
+ else:
451
+ attr_col_headings = [edge_attr]
452
+ if len(attr_col_headings) == 0:
453
+ raise nx.NetworkXError(
454
+ f"Invalid edge_attr argument: No columns found with name: {attr_col_headings}"
455
+ )
456
+
457
+ try:
458
+ attribute_data = zip(*[df[col] for col in attr_col_headings])
459
+ except (KeyError, TypeError) as err:
460
+ msg = f"Invalid edge_attr argument: {edge_attr}"
461
+ raise nx.NetworkXError(msg) from err
462
+
463
+ if g.is_multigraph():
464
+ # => append the edge keys from the df to the bundled data
465
+ if edge_key is not None:
466
+ try:
467
+ multigraph_edge_keys = df[edge_key]
468
+ attribute_data = zip(attribute_data, multigraph_edge_keys)
469
+ except (KeyError, TypeError) as err:
470
+ msg = f"Invalid edge_key argument: {edge_key}"
471
+ raise nx.NetworkXError(msg) from err
472
+
473
+ for s, t, attrs in zip(df[source], df[target], attribute_data):
474
+ if edge_key is not None:
475
+ attrs, multigraph_edge_key = attrs
476
+ key = g.add_edge(s, t, key=multigraph_edge_key)
477
+ else:
478
+ key = g.add_edge(s, t)
479
+
480
+ g[s][t][key].update(zip(attr_col_headings, attrs))
481
+ else:
482
+ for s, t, attrs in zip(df[source], df[target], attribute_data):
483
+ g.add_edge(s, t)
484
+ g[s][t].update(zip(attr_col_headings, attrs))
485
+
486
+ return g
487
+
488
+
489
+ @nx._dispatchable(edge_attrs="weight")
490
+ def to_scipy_sparse_array(G, nodelist=None, dtype=None, weight="weight", format="csr"):
491
+ """Returns the graph adjacency matrix as a SciPy sparse array.
492
+
493
+ Parameters
494
+ ----------
495
+ G : graph
496
+ The NetworkX graph used to construct the sparse array.
497
+
498
+ nodelist : list, optional
499
+ The rows and columns are ordered according to the nodes in `nodelist`.
500
+ If `nodelist` is None, then the ordering is produced by ``G.nodes()``.
501
+
502
+ dtype : NumPy data-type, optional
503
+ A valid NumPy dtype used to initialize the array. If None, then the
504
+ NumPy default is used.
505
+
506
+ weight : string or None, optional (default='weight')
507
+ The edge attribute that holds the numerical value used for
508
+ the edge weight. If None then all edge weights are 1.
509
+
510
+ format : str in {'bsr', 'csr', 'csc', 'coo', 'lil', 'dia', 'dok'}
511
+ The format of the sparse array to be returned (default 'csr'). For
512
+ some algorithms different implementations of sparse arrays
513
+ can perform better. See [1]_ for details.
514
+
515
+ Returns
516
+ -------
517
+ A : SciPy sparse array
518
+ Graph adjacency matrix.
519
+
520
+ Notes
521
+ -----
522
+ For directed graphs, matrix entry ``i, j`` corresponds to an edge from
523
+ ``i`` to ``j``.
524
+
525
+ The values of the adjacency matrix are populated using the edge attribute held in
526
+ parameter `weight`. When an edge does not have that attribute, the
527
+ value of the entry is 1.
528
+
529
+ For multiple edges the matrix values are the sums of the edge weights.
530
+
531
+ When `nodelist` does not contain every node in `G`, the adjacency matrix
532
+ is built from the subgraph of `G` that is induced by the nodes in
533
+ `nodelist`.
534
+
535
+ The convention used for self-loop edges in graphs is to assign the
536
+ diagonal matrix entry value to the weight attribute of the edge
537
+ (or the number 1 if the edge has no weight attribute). If the
538
+ alternate convention of doubling the edge weight is desired the
539
+ resulting array can be modified as follows::
540
+
541
+ >>> G = nx.Graph([(1, 1)])
542
+ >>> A = nx.to_scipy_sparse_array(G)
543
+ >>> A.toarray()
544
+ array([[1]])
545
+ >>> A.setdiag(A.diagonal() * 2)
546
+ >>> A.toarray()
547
+ array([[2]])
548
+
549
+ Examples
550
+ --------
551
+
552
+ Basic usage:
553
+
554
+ >>> G = nx.path_graph(4)
555
+ >>> A = nx.to_scipy_sparse_array(G)
556
+ >>> A # doctest: +SKIP
557
+ <Compressed Sparse Row sparse array of dtype 'int64'
558
+ with 6 stored elements and shape (4, 4)>
559
+
560
+ >>> A.toarray()
561
+ array([[0, 1, 0, 0],
562
+ [1, 0, 1, 0],
563
+ [0, 1, 0, 1],
564
+ [0, 0, 1, 0]])
565
+
566
+ .. note:: The `toarray` method is used in these examples to better visualize
567
+ the adjacency matrix. For a dense representation of the adjaceny matrix,
568
+ use `to_numpy_array` instead.
569
+
570
+ Directed graphs:
571
+
572
+ >>> G = nx.DiGraph([(0, 1), (1, 2), (2, 3)])
573
+ >>> nx.to_scipy_sparse_array(G).toarray()
574
+ array([[0, 1, 0, 0],
575
+ [0, 0, 1, 0],
576
+ [0, 0, 0, 1],
577
+ [0, 0, 0, 0]])
578
+
579
+ >>> H = G.reverse()
580
+ >>> H.edges
581
+ OutEdgeView([(1, 0), (2, 1), (3, 2)])
582
+ >>> nx.to_scipy_sparse_array(H).toarray()
583
+ array([[0, 0, 0, 0],
584
+ [1, 0, 0, 0],
585
+ [0, 1, 0, 0],
586
+ [0, 0, 1, 0]])
587
+
588
+ By default, the order of the rows/columns of the adjacency matrix is determined
589
+ by the ordering of the nodes in `G`:
590
+
591
+ >>> G = nx.Graph()
592
+ >>> G.add_nodes_from([3, 5, 0, 1])
593
+ >>> G.add_edges_from([(1, 3), (1, 5)])
594
+ >>> nx.to_scipy_sparse_array(G).toarray()
595
+ array([[0, 0, 0, 1],
596
+ [0, 0, 0, 1],
597
+ [0, 0, 0, 0],
598
+ [1, 1, 0, 0]])
599
+
600
+ The ordering of the rows can be changed with `nodelist`:
601
+
602
+ >>> ordered = [0, 1, 3, 5]
603
+ >>> nx.to_scipy_sparse_array(G, nodelist=ordered).toarray()
604
+ array([[0, 0, 0, 0],
605
+ [0, 0, 1, 1],
606
+ [0, 1, 0, 0],
607
+ [0, 1, 0, 0]])
608
+
609
+ If `nodelist` contains a subset of the nodes in `G`, the adjacency matrix
610
+ for the node-induced subgraph is produced:
611
+
612
+ >>> nx.to_scipy_sparse_array(G, nodelist=[1, 3, 5]).toarray()
613
+ array([[0, 1, 1],
614
+ [1, 0, 0],
615
+ [1, 0, 0]])
616
+
617
+ The values of the adjacency matrix are drawn from the edge attribute
618
+ specified by the `weight` parameter:
619
+
620
+ >>> G = nx.path_graph(4)
621
+ >>> nx.set_edge_attributes(
622
+ ... G, values={(0, 1): 1, (1, 2): 10, (2, 3): 2}, name="weight"
623
+ ... )
624
+ >>> nx.set_edge_attributes(
625
+ ... G, values={(0, 1): 50, (1, 2): 35, (2, 3): 10}, name="capacity"
626
+ ... )
627
+ >>> nx.to_scipy_sparse_array(G).toarray() # Default weight="weight"
628
+ array([[ 0, 1, 0, 0],
629
+ [ 1, 0, 10, 0],
630
+ [ 0, 10, 0, 2],
631
+ [ 0, 0, 2, 0]])
632
+ >>> nx.to_scipy_sparse_array(G, weight="capacity").toarray()
633
+ array([[ 0, 50, 0, 0],
634
+ [50, 0, 35, 0],
635
+ [ 0, 35, 0, 10],
636
+ [ 0, 0, 10, 0]])
637
+
638
+ Any edges that don't have a `weight` attribute default to 1:
639
+
640
+ >>> G[1][2].pop("capacity")
641
+ 35
642
+ >>> nx.to_scipy_sparse_array(G, weight="capacity").toarray()
643
+ array([[ 0, 50, 0, 0],
644
+ [50, 0, 1, 0],
645
+ [ 0, 1, 0, 10],
646
+ [ 0, 0, 10, 0]])
647
+
648
+ When `G` is a multigraph, the values in the adjacency matrix are given by
649
+ the sum of the `weight` edge attribute over each edge key:
650
+
651
+ >>> G = nx.MultiDiGraph([(0, 1), (0, 1), (0, 1), (2, 0)])
652
+ >>> nx.to_scipy_sparse_array(G).toarray()
653
+ array([[0, 3, 0],
654
+ [0, 0, 0],
655
+ [1, 0, 0]])
656
+
657
+ References
658
+ ----------
659
+ .. [1] Scipy Dev. References, "Sparse Arrays",
660
+ https://docs.scipy.org/doc/scipy/reference/sparse.html
661
+ """
662
+ import scipy as sp
663
+
664
+ if len(G) == 0:
665
+ raise nx.NetworkXError("Graph has no nodes or edges")
666
+
667
+ if nodelist is None:
668
+ nodelist = list(G)
669
+ nlen = len(G)
670
+ else:
671
+ nlen = len(nodelist)
672
+ if nlen == 0:
673
+ raise nx.NetworkXError("nodelist has no nodes")
674
+ nodeset = set(G.nbunch_iter(nodelist))
675
+ if nlen != len(nodeset):
676
+ for n in nodelist:
677
+ if n not in G:
678
+ raise nx.NetworkXError(f"Node {n} in nodelist is not in G")
679
+ raise nx.NetworkXError("nodelist contains duplicates.")
680
+ if nlen < len(G):
681
+ G = G.subgraph(nodelist)
682
+
683
+ index = dict(zip(nodelist, range(nlen)))
684
+ coefficients = zip(
685
+ *((index[u], index[v], wt) for u, v, wt in G.edges(data=weight, default=1))
686
+ )
687
+ try:
688
+ row, col, data = coefficients
689
+ except ValueError:
690
+ # there is no edge in the subgraph
691
+ row, col, data = [], [], []
692
+
693
+ if G.is_directed():
694
+ A = sp.sparse.coo_array((data, (row, col)), shape=(nlen, nlen), dtype=dtype)
695
+ else:
696
+ # symmetrize matrix
697
+ d = data + data
698
+ r = row + col
699
+ c = col + row
700
+ # selfloop entries get double counted when symmetrizing
701
+ # so we subtract the data on the diagonal
702
+ selfloops = list(nx.selfloop_edges(G, data=weight, default=1))
703
+ if selfloops:
704
+ diag_index, diag_data = zip(*((index[u], -wt) for u, v, wt in selfloops))
705
+ d += diag_data
706
+ r += diag_index
707
+ c += diag_index
708
+ A = sp.sparse.coo_array((d, (r, c)), shape=(nlen, nlen), dtype=dtype)
709
+ try:
710
+ return A.asformat(format)
711
+ except ValueError as err:
712
+ raise nx.NetworkXError(f"Unknown sparse matrix format: {format}") from err
713
+
714
+
715
+ def _csr_gen_triples(A):
716
+ """Converts a SciPy sparse array in **Compressed Sparse Row** format to
717
+ an iterable of weighted edge triples.
718
+
719
+ """
720
+ nrows = A.shape[0]
721
+ indptr, dst_indices, data = A.indptr, A.indices, A.data
722
+ import numpy as np
723
+
724
+ src_indices = np.repeat(np.arange(nrows), np.diff(indptr))
725
+ return zip(src_indices.tolist(), dst_indices.tolist(), A.data.tolist())
726
+
727
+
728
+ def _csc_gen_triples(A):
729
+ """Converts a SciPy sparse array in **Compressed Sparse Column** format to
730
+ an iterable of weighted edge triples.
731
+
732
+ """
733
+ ncols = A.shape[1]
734
+ indptr, src_indices, data = A.indptr, A.indices, A.data
735
+ import numpy as np
736
+
737
+ dst_indices = np.repeat(np.arange(ncols), np.diff(indptr))
738
+ return zip(src_indices.tolist(), dst_indices.tolist(), A.data.tolist())
739
+
740
+
741
+ def _coo_gen_triples(A):
742
+ """Converts a SciPy sparse array in **Coordinate** format to an iterable
743
+ of weighted edge triples.
744
+
745
+ """
746
+ return zip(A.row.tolist(), A.col.tolist(), A.data.tolist())
747
+
748
+
749
+ def _dok_gen_triples(A):
750
+ """Converts a SciPy sparse array in **Dictionary of Keys** format to an
751
+ iterable of weighted edge triples.
752
+
753
+ """
754
+ for (r, c), v in A.items():
755
+ # Use `v.item()` to convert a NumPy scalar to the appropriate Python scalar
756
+ yield int(r), int(c), v.item()
757
+
758
+
759
+ def _generate_weighted_edges(A):
760
+ """Returns an iterable over (u, v, w) triples, where u and v are adjacent
761
+ vertices and w is the weight of the edge joining u and v.
762
+
763
+ `A` is a SciPy sparse array (in any format).
764
+
765
+ """
766
+ if A.format == "csr":
767
+ return _csr_gen_triples(A)
768
+ if A.format == "csc":
769
+ return _csc_gen_triples(A)
770
+ if A.format == "dok":
771
+ return _dok_gen_triples(A)
772
+ # If A is in any other format (including COO), convert it to COO format.
773
+ return _coo_gen_triples(A.tocoo())
774
+
775
+
776
+ @nx._dispatchable(graphs=None, returns_graph=True)
777
+ def from_scipy_sparse_array(
778
+ A, parallel_edges=False, create_using=None, edge_attribute="weight"
779
+ ):
780
+ """Creates a new graph from an adjacency matrix given as a SciPy sparse
781
+ array.
782
+
783
+ Parameters
784
+ ----------
785
+ A: scipy.sparse array
786
+ An adjacency matrix representation of a graph
787
+
788
+ parallel_edges : Boolean
789
+ If this is True, `create_using` is a multigraph, and `A` is an
790
+ integer matrix, then entry *(i, j)* in the matrix is interpreted as the
791
+ number of parallel edges joining vertices *i* and *j* in the graph.
792
+ If it is False, then the entries in the matrix are interpreted as
793
+ the weight of a single edge joining the vertices.
794
+
795
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
796
+ Graph type to create. If graph instance, then cleared before populated.
797
+
798
+ edge_attribute: string
799
+ Name of edge attribute to store matrix numeric value. The data will
800
+ have the same type as the matrix entry (int, float, (real,imag)).
801
+
802
+ Notes
803
+ -----
804
+ For directed graphs, explicitly mention create_using=nx.DiGraph,
805
+ and entry i,j of A corresponds to an edge from i to j.
806
+
807
+ If `create_using` is :class:`networkx.MultiGraph` or
808
+ :class:`networkx.MultiDiGraph`, `parallel_edges` is True, and the
809
+ entries of `A` are of type :class:`int`, then this function returns a
810
+ multigraph (constructed from `create_using`) with parallel edges.
811
+ In this case, `edge_attribute` will be ignored.
812
+
813
+ If `create_using` indicates an undirected multigraph, then only the edges
814
+ indicated by the upper triangle of the matrix `A` will be added to the
815
+ graph.
816
+
817
+ Examples
818
+ --------
819
+ >>> import scipy as sp
820
+ >>> A = sp.sparse.eye(2, 2, 1)
821
+ >>> G = nx.from_scipy_sparse_array(A)
822
+
823
+ If `create_using` indicates a multigraph and the matrix has only integer
824
+ entries and `parallel_edges` is False, then the entries will be treated
825
+ as weights for edges joining the nodes (without creating parallel edges):
826
+
827
+ >>> A = sp.sparse.csr_array([[1, 1], [1, 2]])
828
+ >>> G = nx.from_scipy_sparse_array(A, create_using=nx.MultiGraph)
829
+ >>> G[1][1]
830
+ AtlasView({0: {'weight': 2}})
831
+
832
+ If `create_using` indicates a multigraph and the matrix has only integer
833
+ entries and `parallel_edges` is True, then the entries will be treated
834
+ as the number of parallel edges joining those two vertices:
835
+
836
+ >>> A = sp.sparse.csr_array([[1, 1], [1, 2]])
837
+ >>> G = nx.from_scipy_sparse_array(
838
+ ... A, parallel_edges=True, create_using=nx.MultiGraph
839
+ ... )
840
+ >>> G[1][1]
841
+ AtlasView({0: {'weight': 1}, 1: {'weight': 1}})
842
+
843
+ """
844
+ G = nx.empty_graph(0, create_using)
845
+ n, m = A.shape
846
+ if n != m:
847
+ raise nx.NetworkXError(f"Adjacency matrix not square: nx,ny={A.shape}")
848
+ # Make sure we get even the isolated nodes of the graph.
849
+ G.add_nodes_from(range(n))
850
+ # Create an iterable over (u, v, w) triples and for each triple, add an
851
+ # edge from u to v with weight w.
852
+ triples = _generate_weighted_edges(A)
853
+ # If the entries in the adjacency matrix are integers, the graph is a
854
+ # multigraph, and parallel_edges is True, then create parallel edges, each
855
+ # with weight 1, for each entry in the adjacency matrix. Otherwise, create
856
+ # one edge for each positive entry in the adjacency matrix and set the
857
+ # weight of that edge to be the entry in the matrix.
858
+ if A.dtype.kind in ("i", "u") and G.is_multigraph() and parallel_edges:
859
+ chain = itertools.chain.from_iterable
860
+ # The following line is equivalent to:
861
+ #
862
+ # for (u, v) in edges:
863
+ # for d in range(A[u, v]):
864
+ # G.add_edge(u, v, weight=1)
865
+ #
866
+ triples = chain(((u, v, 1) for d in range(w)) for (u, v, w) in triples)
867
+ # If we are creating an undirected multigraph, only add the edges from the
868
+ # upper triangle of the matrix. Otherwise, add all the edges. This relies
869
+ # on the fact that the vertices created in the
870
+ # `_generated_weighted_edges()` function are actually the row/column
871
+ # indices for the matrix `A`.
872
+ #
873
+ # Without this check, we run into a problem where each edge is added twice
874
+ # when `G.add_weighted_edges_from()` is invoked below.
875
+ if G.is_multigraph() and not G.is_directed():
876
+ triples = ((u, v, d) for u, v, d in triples if u <= v)
877
+ G.add_weighted_edges_from(triples, weight=edge_attribute)
878
+ return G
879
+
880
+
881
+ @nx._dispatchable(edge_attrs="weight") # edge attrs may also be obtained from `dtype`
882
+ def to_numpy_array(
883
+ G,
884
+ nodelist=None,
885
+ dtype=None,
886
+ order=None,
887
+ multigraph_weight=sum,
888
+ weight="weight",
889
+ nonedge=0.0,
890
+ ):
891
+ """Returns the graph adjacency matrix as a NumPy array.
892
+
893
+ Parameters
894
+ ----------
895
+ G : graph
896
+ The NetworkX graph used to construct the NumPy array.
897
+
898
+ nodelist : list, optional
899
+ The rows and columns are ordered according to the nodes in `nodelist`.
900
+ If `nodelist` is ``None``, then the ordering is produced by ``G.nodes()``.
901
+
902
+ dtype : NumPy data type, optional
903
+ A NumPy data type used to initialize the array. If None, then the NumPy
904
+ default is used. The dtype can be structured if `weight=None`, in which
905
+ case the dtype field names are used to look up edge attributes. The
906
+ result is a structured array where each named field in the dtype
907
+ corresponds to the adjacency for that edge attribute. See examples for
908
+ details.
909
+
910
+ order : {'C', 'F'}, optional
911
+ Whether to store multidimensional data in C- or Fortran-contiguous
912
+ (row- or column-wise) order in memory. If None, then the NumPy default
913
+ is used.
914
+
915
+ multigraph_weight : callable, optional
916
+ An function that determines how weights in multigraphs are handled.
917
+ The function should accept a sequence of weights and return a single
918
+ value. The default is to sum the weights of the multiple edges.
919
+
920
+ weight : string or None optional (default = 'weight')
921
+ The edge attribute that holds the numerical value used for
922
+ the edge weight. If an edge does not have that attribute, then the
923
+ value 1 is used instead. `weight` must be ``None`` if a structured
924
+ dtype is used.
925
+
926
+ nonedge : array_like (default = 0.0)
927
+ The value used to represent non-edges in the adjacency matrix.
928
+ The array values corresponding to nonedges are typically set to zero.
929
+ However, this could be undesirable if there are array values
930
+ corresponding to actual edges that also have the value zero. If so,
931
+ one might prefer nonedges to have some other value, such as ``nan``.
932
+
933
+ Returns
934
+ -------
935
+ A : NumPy ndarray
936
+ Graph adjacency matrix
937
+
938
+ Raises
939
+ ------
940
+ NetworkXError
941
+ If `dtype` is a structured dtype and `G` is a multigraph
942
+ ValueError
943
+ If `dtype` is a structured dtype and `weight` is not `None`
944
+
945
+ See Also
946
+ --------
947
+ from_numpy_array
948
+
949
+ Notes
950
+ -----
951
+ For directed graphs, entry ``i, j`` corresponds to an edge from ``i`` to ``j``.
952
+
953
+ Entries in the adjacency matrix are given by the `weight` edge attribute.
954
+ When an edge does not have a weight attribute, the value of the entry is
955
+ set to the number 1. For multiple (parallel) edges, the values of the
956
+ entries are determined by the `multigraph_weight` parameter. The default is
957
+ to sum the weight attributes for each of the parallel edges.
958
+
959
+ When `nodelist` does not contain every node in `G`, the adjacency matrix is
960
+ built from the subgraph of `G` that is induced by the nodes in `nodelist`.
961
+
962
+ The convention used for self-loop edges in graphs is to assign the
963
+ diagonal array entry value to the weight attribute of the edge
964
+ (or the number 1 if the edge has no weight attribute). If the
965
+ alternate convention of doubling the edge weight is desired the
966
+ resulting NumPy array can be modified as follows:
967
+
968
+ >>> import numpy as np
969
+ >>> G = nx.Graph([(1, 1)])
970
+ >>> A = nx.to_numpy_array(G)
971
+ >>> A
972
+ array([[1.]])
973
+ >>> A[np.diag_indices_from(A)] *= 2
974
+ >>> A
975
+ array([[2.]])
976
+
977
+ Examples
978
+ --------
979
+ >>> G = nx.MultiDiGraph()
980
+ >>> G.add_edge(0, 1, weight=2)
981
+ 0
982
+ >>> G.add_edge(1, 0)
983
+ 0
984
+ >>> G.add_edge(2, 2, weight=3)
985
+ 0
986
+ >>> G.add_edge(2, 2)
987
+ 1
988
+ >>> nx.to_numpy_array(G, nodelist=[0, 1, 2])
989
+ array([[0., 2., 0.],
990
+ [1., 0., 0.],
991
+ [0., 0., 4.]])
992
+
993
+ When `nodelist` argument is used, nodes of `G` which do not appear in the `nodelist`
994
+ and their edges are not included in the adjacency matrix. Here is an example:
995
+
996
+ >>> G = nx.Graph()
997
+ >>> G.add_edge(3, 1)
998
+ >>> G.add_edge(2, 0)
999
+ >>> G.add_edge(2, 1)
1000
+ >>> G.add_edge(3, 0)
1001
+ >>> nx.to_numpy_array(G, nodelist=[1, 2, 3])
1002
+ array([[0., 1., 1.],
1003
+ [1., 0., 0.],
1004
+ [1., 0., 0.]])
1005
+
1006
+ This function can also be used to create adjacency matrices for multiple
1007
+ edge attributes with structured dtypes:
1008
+
1009
+ >>> G = nx.Graph()
1010
+ >>> G.add_edge(0, 1, weight=10)
1011
+ >>> G.add_edge(1, 2, cost=5)
1012
+ >>> G.add_edge(2, 3, weight=3, cost=-4.0)
1013
+ >>> dtype = np.dtype([("weight", int), ("cost", float)])
1014
+ >>> A = nx.to_numpy_array(G, dtype=dtype, weight=None)
1015
+ >>> A["weight"]
1016
+ array([[ 0, 10, 0, 0],
1017
+ [10, 0, 1, 0],
1018
+ [ 0, 1, 0, 3],
1019
+ [ 0, 0, 3, 0]])
1020
+ >>> A["cost"]
1021
+ array([[ 0., 1., 0., 0.],
1022
+ [ 1., 0., 5., 0.],
1023
+ [ 0., 5., 0., -4.],
1024
+ [ 0., 0., -4., 0.]])
1025
+
1026
+ As stated above, the argument "nonedge" is useful especially when there are
1027
+ actually edges with weight 0 in the graph. Setting a nonedge value different than 0,
1028
+ makes it much clearer to differentiate such 0-weighted edges and actual nonedge values.
1029
+
1030
+ >>> G = nx.Graph()
1031
+ >>> G.add_edge(3, 1, weight=2)
1032
+ >>> G.add_edge(2, 0, weight=0)
1033
+ >>> G.add_edge(2, 1, weight=0)
1034
+ >>> G.add_edge(3, 0, weight=1)
1035
+ >>> nx.to_numpy_array(G, nonedge=-1.0)
1036
+ array([[-1., 2., -1., 1.],
1037
+ [ 2., -1., 0., -1.],
1038
+ [-1., 0., -1., 0.],
1039
+ [ 1., -1., 0., -1.]])
1040
+ """
1041
+ import numpy as np
1042
+
1043
+ if nodelist is None:
1044
+ nodelist = list(G)
1045
+ nlen = len(nodelist)
1046
+
1047
+ # Input validation
1048
+ nodeset = set(nodelist)
1049
+ if nodeset - set(G):
1050
+ raise nx.NetworkXError(f"Nodes {nodeset - set(G)} in nodelist is not in G")
1051
+ if len(nodeset) < nlen:
1052
+ raise nx.NetworkXError("nodelist contains duplicates.")
1053
+
1054
+ A = np.full((nlen, nlen), fill_value=nonedge, dtype=dtype, order=order)
1055
+
1056
+ # Corner cases: empty nodelist or graph without any edges
1057
+ if nlen == 0 or G.number_of_edges() == 0:
1058
+ return A
1059
+
1060
+ # If dtype is structured and weight is None, use dtype field names as
1061
+ # edge attributes
1062
+ edge_attrs = None # Only single edge attribute by default
1063
+ if A.dtype.names:
1064
+ if weight is None:
1065
+ edge_attrs = dtype.names
1066
+ else:
1067
+ raise ValueError(
1068
+ "Specifying `weight` not supported for structured dtypes\n."
1069
+ "To create adjacency matrices from structured dtypes, use `weight=None`."
1070
+ )
1071
+
1072
+ # Map nodes to row/col in matrix
1073
+ idx = dict(zip(nodelist, range(nlen)))
1074
+ if len(nodelist) < len(G):
1075
+ G = G.subgraph(nodelist).copy()
1076
+
1077
+ # Collect all edge weights and reduce with `multigraph_weights`
1078
+ if G.is_multigraph():
1079
+ if edge_attrs:
1080
+ raise nx.NetworkXError(
1081
+ "Structured arrays are not supported for MultiGraphs"
1082
+ )
1083
+ d = defaultdict(list)
1084
+ for u, v, wt in G.edges(data=weight, default=1.0):
1085
+ d[(idx[u], idx[v])].append(wt)
1086
+ i, j = np.array(list(d.keys())).T # indices
1087
+ wts = [multigraph_weight(ws) for ws in d.values()] # reduced weights
1088
+ else:
1089
+ i, j, wts = [], [], []
1090
+
1091
+ # Special branch: multi-attr adjacency from structured dtypes
1092
+ if edge_attrs:
1093
+ # Extract edges with all data
1094
+ for u, v, data in G.edges(data=True):
1095
+ i.append(idx[u])
1096
+ j.append(idx[v])
1097
+ wts.append(data)
1098
+ # Map each attribute to the appropriate named field in the
1099
+ # structured dtype
1100
+ for attr in edge_attrs:
1101
+ attr_data = [wt.get(attr, 1.0) for wt in wts]
1102
+ A[attr][i, j] = attr_data
1103
+ if not G.is_directed():
1104
+ A[attr][j, i] = attr_data
1105
+ return A
1106
+
1107
+ for u, v, wt in G.edges(data=weight, default=1.0):
1108
+ i.append(idx[u])
1109
+ j.append(idx[v])
1110
+ wts.append(wt)
1111
+
1112
+ # Set array values with advanced indexing
1113
+ A[i, j] = wts
1114
+ if not G.is_directed():
1115
+ A[j, i] = wts
1116
+
1117
+ return A
1118
+
1119
+
1120
+ @nx._dispatchable(graphs=None, returns_graph=True)
1121
+ def from_numpy_array(
1122
+ A, parallel_edges=False, create_using=None, edge_attr="weight", *, nodelist=None
1123
+ ):
1124
+ """Returns a graph from a 2D NumPy array.
1125
+
1126
+ The 2D NumPy array is interpreted as an adjacency matrix for the graph.
1127
+
1128
+ Parameters
1129
+ ----------
1130
+ A : a 2D numpy.ndarray
1131
+ An adjacency matrix representation of a graph
1132
+
1133
+ parallel_edges : Boolean
1134
+ If this is True, `create_using` is a multigraph, and `A` is an
1135
+ integer array, then entry *(i, j)* in the array is interpreted as the
1136
+ number of parallel edges joining vertices *i* and *j* in the graph.
1137
+ If it is False, then the entries in the array are interpreted as
1138
+ the weight of a single edge joining the vertices.
1139
+
1140
+ create_using : NetworkX graph constructor, optional (default=nx.Graph)
1141
+ Graph type to create. If graph instance, then cleared before populated.
1142
+
1143
+ edge_attr : String, optional (default="weight")
1144
+ The attribute to which the array values are assigned on each edge. If
1145
+ it is None, edge attributes will not be assigned.
1146
+
1147
+ nodelist : sequence of nodes, optional
1148
+ A sequence of objects to use as the nodes in the graph. If provided, the
1149
+ list of nodes must be the same length as the dimensions of `A`. The
1150
+ default is `None`, in which case the nodes are drawn from ``range(n)``.
1151
+
1152
+ Notes
1153
+ -----
1154
+ For directed graphs, explicitly mention create_using=nx.DiGraph,
1155
+ and entry i,j of A corresponds to an edge from i to j.
1156
+
1157
+ If `create_using` is :class:`networkx.MultiGraph` or
1158
+ :class:`networkx.MultiDiGraph`, `parallel_edges` is True, and the
1159
+ entries of `A` are of type :class:`int`, then this function returns a
1160
+ multigraph (of the same type as `create_using`) with parallel edges.
1161
+
1162
+ If `create_using` indicates an undirected multigraph, then only the edges
1163
+ indicated by the upper triangle of the array `A` will be added to the
1164
+ graph.
1165
+
1166
+ If `edge_attr` is Falsy (False or None), edge attributes will not be
1167
+ assigned, and the array data will be treated like a binary mask of
1168
+ edge presence or absence. Otherwise, the attributes will be assigned
1169
+ as follows:
1170
+
1171
+ If the NumPy array has a single data type for each array entry it
1172
+ will be converted to an appropriate Python data type.
1173
+
1174
+ If the NumPy array has a user-specified compound data type the names
1175
+ of the data fields will be used as attribute keys in the resulting
1176
+ NetworkX graph.
1177
+
1178
+ See Also
1179
+ --------
1180
+ to_numpy_array
1181
+
1182
+ Examples
1183
+ --------
1184
+ Simple integer weights on edges:
1185
+
1186
+ >>> import numpy as np
1187
+ >>> A = np.array([[1, 1], [2, 1]])
1188
+ >>> G = nx.from_numpy_array(A)
1189
+ >>> G.edges(data=True)
1190
+ EdgeDataView([(0, 0, {'weight': 1}), (0, 1, {'weight': 2}), (1, 1, {'weight': 1})])
1191
+
1192
+ If `create_using` indicates a multigraph and the array has only integer
1193
+ entries and `parallel_edges` is False, then the entries will be treated
1194
+ as weights for edges joining the nodes (without creating parallel edges):
1195
+
1196
+ >>> A = np.array([[1, 1], [1, 2]])
1197
+ >>> G = nx.from_numpy_array(A, create_using=nx.MultiGraph)
1198
+ >>> G[1][1]
1199
+ AtlasView({0: {'weight': 2}})
1200
+
1201
+ If `create_using` indicates a multigraph and the array has only integer
1202
+ entries and `parallel_edges` is True, then the entries will be treated
1203
+ as the number of parallel edges joining those two vertices:
1204
+
1205
+ >>> A = np.array([[1, 1], [1, 2]])
1206
+ >>> temp = nx.MultiGraph()
1207
+ >>> G = nx.from_numpy_array(A, parallel_edges=True, create_using=temp)
1208
+ >>> G[1][1]
1209
+ AtlasView({0: {'weight': 1}, 1: {'weight': 1}})
1210
+
1211
+ User defined compound data type on edges:
1212
+
1213
+ >>> dt = [("weight", float), ("cost", int)]
1214
+ >>> A = np.array([[(1.0, 2)]], dtype=dt)
1215
+ >>> G = nx.from_numpy_array(A)
1216
+ >>> G.edges()
1217
+ EdgeView([(0, 0)])
1218
+ >>> G[0][0]["cost"]
1219
+ 2
1220
+ >>> G[0][0]["weight"]
1221
+ 1.0
1222
+
1223
+ """
1224
+ kind_to_python_type = {
1225
+ "f": float,
1226
+ "i": int,
1227
+ "u": int,
1228
+ "b": bool,
1229
+ "c": complex,
1230
+ "S": str,
1231
+ "U": str,
1232
+ "V": "void",
1233
+ }
1234
+ G = nx.empty_graph(0, create_using)
1235
+ if A.ndim != 2:
1236
+ raise nx.NetworkXError(f"Input array must be 2D, not {A.ndim}")
1237
+ n, m = A.shape
1238
+ if n != m:
1239
+ raise nx.NetworkXError(f"Adjacency matrix not square: nx,ny={A.shape}")
1240
+ dt = A.dtype
1241
+ try:
1242
+ python_type = kind_to_python_type[dt.kind]
1243
+ except Exception as err:
1244
+ raise TypeError(f"Unknown numpy data type: {dt}") from err
1245
+ if _default_nodes := (nodelist is None):
1246
+ nodelist = range(n)
1247
+ else:
1248
+ if len(nodelist) != n:
1249
+ raise ValueError("nodelist must have the same length as A.shape[0]")
1250
+
1251
+ # Make sure we get even the isolated nodes of the graph.
1252
+ G.add_nodes_from(nodelist)
1253
+ # Get a list of all the entries in the array with nonzero entries. These
1254
+ # coordinates become edges in the graph. (convert to int from np.int64)
1255
+ edges = ((int(e[0]), int(e[1])) for e in zip(*A.nonzero()))
1256
+ # handle numpy constructed data type
1257
+ if python_type == "void":
1258
+ # Sort the fields by their offset, then by dtype, then by name.
1259
+ fields = sorted(
1260
+ (offset, dtype, name) for name, (dtype, offset) in A.dtype.fields.items()
1261
+ )
1262
+ triples = (
1263
+ (
1264
+ u,
1265
+ v,
1266
+ {}
1267
+ if edge_attr in [False, None]
1268
+ else {
1269
+ name: kind_to_python_type[dtype.kind](val)
1270
+ for (_, dtype, name), val in zip(fields, A[u, v])
1271
+ },
1272
+ )
1273
+ for u, v in edges
1274
+ )
1275
+ # If the entries in the adjacency matrix are integers, the graph is a
1276
+ # multigraph, and parallel_edges is True, then create parallel edges, each
1277
+ # with weight 1, for each entry in the adjacency matrix. Otherwise, create
1278
+ # one edge for each positive entry in the adjacency matrix and set the
1279
+ # weight of that edge to be the entry in the matrix.
1280
+ elif python_type is int and G.is_multigraph() and parallel_edges:
1281
+ chain = itertools.chain.from_iterable
1282
+ # The following line is equivalent to:
1283
+ #
1284
+ # for (u, v) in edges:
1285
+ # for d in range(A[u, v]):
1286
+ # G.add_edge(u, v, weight=1)
1287
+ #
1288
+ if edge_attr in [False, None]:
1289
+ triples = chain(((u, v, {}) for d in range(A[u, v])) for (u, v) in edges)
1290
+ else:
1291
+ triples = chain(
1292
+ ((u, v, {edge_attr: 1}) for d in range(A[u, v])) for (u, v) in edges
1293
+ )
1294
+ else: # basic data type
1295
+ if edge_attr in [False, None]:
1296
+ triples = ((u, v, {}) for u, v in edges)
1297
+ else:
1298
+ triples = ((u, v, {edge_attr: python_type(A[u, v])}) for u, v in edges)
1299
+ # If we are creating an undirected multigraph, only add the edges from the
1300
+ # upper triangle of the matrix. Otherwise, add all the edges. This relies
1301
+ # on the fact that the vertices created in the
1302
+ # `_generated_weighted_edges()` function are actually the row/column
1303
+ # indices for the matrix `A`.
1304
+ #
1305
+ # Without this check, we run into a problem where each edge is added twice
1306
+ # when `G.add_edges_from()` is invoked below.
1307
+ if G.is_multigraph() and not G.is_directed():
1308
+ triples = ((u, v, d) for u, v, d in triples if u <= v)
1309
+ # Remap nodes if user provided custom `nodelist`
1310
+ if not _default_nodes:
1311
+ idx_to_node = dict(enumerate(nodelist))
1312
+ triples = ((idx_to_node[u], idx_to_node[v], d) for u, v, d in triples)
1313
+ G.add_edges_from(triples)
1314
+ return G