0
# Core Hypergraph Operations
1
2
Primary hypergraph data structure with construction, manipulation, and basic analysis methods. The Hypergraph class provides the foundation for all hypergraph operations in HyperNetX.
3
4
## Capabilities
5
6
### Hypergraph Construction
7
8
Create hypergraphs from various data sources including pandas DataFrames, dictionaries, lists, and numpy arrays. Supports flexible property and weight specification.
9
10
```python { .api }
11
class Hypergraph:
12
def __init__(
13
self,
14
setsystem: Union[DataFrame, Dict, List, ndarray, None] = None,
15
default_cell_weight: Union[int, float] = 1,
16
edge_col: int = 0,
17
node_col: int = 1,
18
cell_weight_col: str = "weight",
19
misc_cell_properties_col: Optional[str] = None,
20
aggregate_by: str = "first",
21
properties: Union[DataFrame, Dict, None] = None,
22
misc_properties_col: Optional[str] = None,
23
weight_prop_col: str = "weight",
24
default_weight: Union[int, float] = 1,
25
edge_properties: Union[DataFrame, Dict, None] = None,
26
misc_edge_properties_col: Optional[str] = None,
27
edge_weight_prop_col: str = "weight",
28
default_edge_weight: Union[int, float] = 1,
29
node_properties: Union[DataFrame, Dict, None] = None,
30
misc_node_properties_col: Optional[str] = None,
31
node_weight_prop_col: str = "weight",
32
default_node_weight: Union[int, float] = 1,
33
name: Optional[str] = None,
34
**kwargs
35
):
36
"""
37
Create a hypergraph from various data sources.
38
39
Parameters:
40
- setsystem: Data source (DataFrame, dict of iterables, dict of dicts, list, array)
41
- default_cell_weight: Default weight for incidence pairs
42
- edge_col, node_col: Column indices for DataFrame input
43
- cell_weight_col: Column name for incidence weights
44
- misc_cell_properties_col: Column for misc cell properties
45
- aggregate_by: Aggregation method for duplicate incidences ("first", "sum", etc.)
46
- properties: Combined properties for all objects
47
- misc_properties_col: Column for misc properties
48
- weight_prop_col: Weight property column name
49
- default_weight: Default weight value
50
- edge_properties, node_properties: Separate property data
51
- misc_edge_properties_col, misc_node_properties_col: Misc property columns
52
- edge_weight_prop_col, node_weight_prop_col: Weight property column names
53
- default_edge_weight, default_node_weight: Default weights
54
- name: Optional hypergraph name
55
- **kwargs: Additional keyword arguments for backward compatibility
56
"""
57
```
58
59
### Alternative Constructors
60
61
Class methods for creating hypergraphs from specialized data formats.
62
63
```python { .api }
64
@classmethod
65
def from_bipartite(
66
cls,
67
B,
68
node_id: int = 1,
69
name: Optional[str] = None,
70
**kwargs
71
) -> "Hypergraph":
72
"""Create hypergraph from NetworkX bipartite graph."""
73
74
@classmethod
75
def from_incidence_matrix(
76
cls,
77
M,
78
name: Optional[str] = None,
79
**kwargs
80
) -> "Hypergraph":
81
"""Create hypergraph from incidence matrix."""
82
83
@classmethod
84
def from_numpy_array(
85
cls,
86
M: ndarray,
87
node_names: Optional[List] = None,
88
edge_names: Optional[List] = None,
89
name: Optional[str] = None,
90
key: Optional[str] = None,
91
**kwargs
92
) -> "Hypergraph":
93
"""Create hypergraph from numpy array."""
94
95
@classmethod
96
def from_incidence_dataframe(
97
cls,
98
df: DataFrame,
99
name: Optional[str] = None,
100
fillna: Any = 0,
101
key: Optional[str] = None,
102
return_only_dataframe: bool = False,
103
**kwargs
104
) -> "Hypergraph":
105
"""Create hypergraph from incidence DataFrame."""
106
```
107
108
### Basic Properties and Structure
109
110
Access fundamental hypergraph properties and structural information.
111
112
```python { .api }
113
def order(self) -> int:
114
"""Number of nodes in the hypergraph."""
115
116
@property
117
def shape(self) -> tuple:
118
"""Tuple of (number of nodes, number of edges)."""
119
120
def degree(
121
self,
122
node_uid: Union[str, int],
123
s: int = 1,
124
max_size: Optional[int] = None
125
) -> int:
126
"""
127
Node degree (number of edges containing the node).
128
129
Parameters:
130
- node_uid: Node identifier
131
- s: Level for s-degree calculation
132
- max_size: Maximum edge size to consider
133
134
Returns:
135
Node degree
136
"""
137
138
def size(
139
self,
140
edge: Union[str, int],
141
nodeset: Optional[set] = None
142
) -> int:
143
"""
144
Edge size (number of nodes in the edge).
145
146
Parameters:
147
- edge: Edge identifier
148
- nodeset: Restrict to nodes in this set
149
150
Returns:
151
Edge size
152
"""
153
154
def dim(self, edge: Union[str, int]) -> int:
155
"""Edge dimension (size - 1)."""
156
157
@property
158
def edges(self) -> "HypergraphView":
159
"""View of hypergraph edges."""
160
161
@property
162
def nodes(self) -> "HypergraphView":
163
"""View of hypergraph nodes."""
164
165
@property
166
def incidences(self) -> "HypergraphView":
167
"""View of hypergraph incidences (edge-node pairs)."""
168
169
@property
170
def incidence_dict(self) -> Dict[Union[str, int], List]:
171
"""Dictionary mapping edge UIDs to lists of node UIDs."""
172
```
173
174
### Matrix Representations
175
176
Convert hypergraph to various matrix formats for analysis and computation.
177
178
```python { .api }
179
def incidence_matrix(
180
self,
181
index: bool = False,
182
weights: bool = False
183
):
184
"""
185
Sparse incidence matrix representation.
186
187
Parameters:
188
- index: Include row/column indices
189
- weights: Include edge/node weights
190
191
Returns:
192
Scipy sparse matrix (and indices if requested)
193
"""
194
195
def incidence_dataframe(self, weights: bool = False) -> DataFrame:
196
"""Incidence matrix as pandas DataFrame."""
197
198
def adjacency_matrix(
199
self,
200
s: int = 1,
201
index: bool = False
202
):
203
"""
204
Node s-adjacency matrix.
205
206
Parameters:
207
- s: Level of adjacency (nodes connected by edges of size ≥ s+1)
208
- index: Include row/column indices
209
210
Returns:
211
Scipy sparse matrix (and indices if requested)
212
"""
213
214
def edge_adjacency_matrix(
215
self,
216
s: int = 1,
217
index: bool = False
218
):
219
"""Edge s-adjacency matrix."""
220
221
def auxiliary_matrix(
222
self,
223
s: int = 1,
224
node: bool = True,
225
index: bool = False
226
):
227
"""Auxiliary matrix for node or edge analysis."""
228
```
229
230
### Adding Elements
231
232
Methods to add nodes, edges, and incidences to the hypergraph.
233
234
```python { .api }
235
def add_node(
236
self,
237
node_uid: Union[str, int],
238
inplace: bool = True,
239
**attr
240
) -> Optional["Hypergraph"]:
241
"""Add a single node with optional attributes."""
242
243
def add_nodes_from(
244
self,
245
node_uids: List[Union[str, int]],
246
inplace: bool = True
247
) -> Optional["Hypergraph"]:
248
"""Add multiple nodes from iterable."""
249
250
def add_edge(
251
self,
252
edge_uid: Union[str, int],
253
inplace: bool = True,
254
**attr
255
) -> Optional["Hypergraph"]:
256
"""Add a single edge with optional attributes."""
257
258
def add_edges_from(
259
self,
260
edge_uids: List[Union[str, int]],
261
inplace: bool = True
262
) -> Optional["Hypergraph"]:
263
"""Add multiple edges from iterable."""
264
265
def add_incidence(
266
self,
267
edge_uid: Union[str, int],
268
node_uid: Union[str, int],
269
inplace: bool = True,
270
**attr
271
) -> Optional["Hypergraph"]:
272
"""Add a single incidence (edge-node pair)."""
273
274
def add_incidences_from(
275
self,
276
incidences: List[tuple],
277
inplace: bool = True
278
) -> Optional["Hypergraph"]:
279
"""Add multiple incidences from iterable of tuples."""
280
281
def add_nodes_to_edges(
282
self,
283
edge_dict: Dict[Union[str, int], List[Union[str, int]]],
284
inplace: bool = True
285
) -> Optional["Hypergraph"]:
286
"""Add nodes to edges using dictionary mapping."""
287
```
288
289
### Removing Elements
290
291
Methods to remove nodes, edges, and incidences from the hypergraph.
292
293
```python { .api }
294
def remove_nodes(
295
self,
296
node_uids: List[Union[str, int]],
297
name: Optional[str] = None,
298
inplace: bool = True
299
) -> Optional["Hypergraph"]:
300
"""Remove nodes and all incident edges."""
301
302
def remove_edges(
303
self,
304
edge_uids: List[Union[str, int]],
305
name: Optional[str] = None,
306
inplace: bool = True
307
) -> Optional["Hypergraph"]:
308
"""Remove edges from hypergraph."""
309
310
def remove_incidences(
311
self,
312
incidence_uids: List[tuple],
313
name: Optional[str] = None,
314
inplace: bool = True
315
) -> Optional["Hypergraph"]:
316
"""Remove specific incidences (edge-node pairs)."""
317
318
def remove_singletons(self, name: Optional[str] = None) -> "Hypergraph":
319
"""Remove singleton edges (edges with only one node)."""
320
```
321
322
### Property Management
323
324
Access and manipulate properties of nodes, edges, and incidences.
325
326
```python { .api }
327
def get_properties(
328
self,
329
uid: Union[str, int, tuple],
330
level: int = 0,
331
prop_name: Optional[str] = None
332
) -> Union[Dict[str, Any], Any]:
333
"""
334
Get properties of a hypergraph object.
335
336
Parameters:
337
- uid: Object identifier (node, edge, or incidence tuple)
338
- level: Object level (0=incidence, 1=node, 2=edge)
339
- prop_name: Specific property name (returns all if None)
340
341
Returns:
342
Property dictionary or specific property value
343
"""
344
345
def get_cell_properties(
346
self,
347
edge_uid: Union[str, int],
348
node_uid: Union[str, int],
349
prop_name: Optional[str] = None
350
) -> Union[Dict[str, Any], Any]:
351
"""Get properties of a specific incidence (cell)."""
352
```
353
354
### Copying and Modification
355
356
Create copies and modify hypergraph structure.
357
358
```python { .api }
359
def clone(self, name: Optional[str] = None) -> "Hypergraph":
360
"""Create a deep copy of the hypergraph."""
361
362
def rename(
363
self,
364
edges: Optional[Dict] = None,
365
nodes: Optional[Dict] = None,
366
name: Optional[str] = None,
367
inplace: bool = True
368
) -> Optional["Hypergraph"]:
369
"""
370
Rename edges and/or nodes.
371
372
Parameters:
373
- edges: Dictionary mapping old edge names to new names
374
- nodes: Dictionary mapping old node names to new names
375
- name: New hypergraph name
376
- inplace: Modify in place or return new hypergraph
377
"""
378
379
def restrict_to_nodes(
380
self,
381
nodes: List[Union[str, int]],
382
name: Optional[str] = None
383
) -> "Hypergraph":
384
"""Create hypergraph restricted to specified nodes."""
385
386
def restrict_to_edges(
387
self,
388
edges: List[Union[str, int]],
389
name: Optional[str] = None
390
) -> "Hypergraph":
391
"""Create hypergraph restricted to specified edges."""
392
```
393
394
### Set Operations
395
396
Combine hypergraphs using set operations.
397
398
```python { .api }
399
def sum(
400
self,
401
other: "Hypergraph",
402
name: Optional[str] = None
403
) -> "Hypergraph":
404
"""Union of two hypergraphs."""
405
406
def union(
407
self,
408
other: "Hypergraph",
409
name: Optional[str] = None
410
) -> "Hypergraph":
411
"""Alias for sum operation."""
412
413
def difference(
414
self,
415
other: "Hypergraph",
416
name: Optional[str] = None
417
) -> "Hypergraph":
418
"""Difference of two hypergraphs."""
419
420
def intersection(
421
self,
422
other: "Hypergraph",
423
name: Optional[str] = None
424
) -> "Hypergraph":
425
"""Intersection of two hypergraphs."""
426
```
427
428
### Specialized Operations
429
430
Advanced operations for hypergraph analysis and transformation.
431
432
```python { .api }
433
def dual(
434
self,
435
name: Optional[str] = None,
436
share_properties: bool = True
437
) -> "Hypergraph":
438
"""Create dual hypergraph (edges become nodes, nodes become edges)."""
439
440
def bipartite(
441
self,
442
keep_data: bool = False,
443
directed: bool = False
444
):
445
"""Convert to NetworkX bipartite graph representation."""
446
447
def toplexes(self, return_hyp: bool = False):
448
"""
449
Get maximal edges (toplexes) - edges not contained in any other edge.
450
451
Parameters:
452
- return_hyp: Return as new hypergraph if True, otherwise return set
453
454
Returns:
455
Set of toplex edge UIDs or new Hypergraph
456
"""
457
458
def singletons(self) -> set:
459
"""Get singleton edges (edges containing only one node)."""
460
461
def edge_size_dist(self) -> Dict[int, int]:
462
"""Distribution of edge sizes."""
463
464
def collapse_edges(
465
self,
466
use_reps: Optional[Dict] = None,
467
use_keys: Optional[str] = None,
468
return_new: bool = False,
469
name: Optional[str] = None
470
) -> Optional["Hypergraph"]:
471
"""Collapse duplicate or similar edges."""
472
473
def collapse_nodes(
474
self,
475
use_reps: Optional[Dict] = None,
476
use_keys: Optional[str] = None,
477
return_new: bool = False,
478
name: Optional[str] = None
479
) -> Optional["Hypergraph"]:
480
"""Collapse duplicate or similar nodes."""
481
482
def collapse_nodes_and_edges(
483
self,
484
node_reps: Optional[Dict] = None,
485
edge_reps: Optional[Dict] = None,
486
node_keys: Optional[str] = None,
487
edge_keys: Optional[str] = None,
488
return_new: bool = False,
489
name: Optional[str] = None
490
) -> Optional["Hypergraph"]:
491
"""Collapse both nodes and edges simultaneously."""
492
```
493
494
### Neighborhood and Relationships
495
496
Query node and edge relationships and neighborhoods.
497
498
```python { .api }
499
def neighbors(
500
self,
501
node: Union[str, int],
502
s: int = 1
503
) -> set:
504
"""
505
Get s-neighbors of a node.
506
507
Parameters:
508
- node: Node identifier
509
- s: Neighborhood level (nodes connected through edges of size ≥ s+1)
510
511
Returns:
512
Set of neighboring node UIDs
513
"""
514
515
def edge_neighbors(
516
self,
517
edge: Union[str, int],
518
s: int = 1
519
) -> set:
520
"""Get s-neighbors of an edge."""
521
```
522
523
### Connectivity Analysis
524
525
Methods for analyzing hypergraph connectivity at different levels.
526
527
```python { .api }
528
def is_connected(
529
self,
530
s: int = 1,
531
edges: bool = False
532
) -> bool:
533
"""
534
Check if hypergraph is s-connected.
535
536
Parameters:
537
- s: Connectivity level
538
- edges: Check edge connectivity instead of node connectivity
539
540
Returns:
541
Boolean indicating connectivity
542
"""
543
544
def s_connected_components(
545
self,
546
s: int = 1,
547
edges: bool = True,
548
return_singletons: bool = False
549
) -> List[set]:
550
"""
551
Find s-connected components.
552
553
Parameters:
554
- s: Connectivity level
555
- edges: Return edge components (True) or node components (False)
556
- return_singletons: Include singleton components
557
558
Returns:
559
List of sets containing component members
560
"""
561
562
def s_component_subgraphs(
563
self,
564
s: int = 1,
565
edges: bool = True,
566
return_singletons: bool = False,
567
name: Optional[str] = None
568
) -> List["Hypergraph"]:
569
"""Get subgraphs for each s-connected component."""
570
571
def s_components(
572
self,
573
s: int = 1,
574
edges: bool = True,
575
return_singletons: bool = True
576
) -> List[set]:
577
"""Alias for s_connected_components."""
578
579
def connected_components(
580
self,
581
edges: bool = False
582
) -> List[set]:
583
"""Find connected components (s=1)."""
584
585
def connected_component_subgraphs(
586
self,
587
return_singletons: bool = True,
588
name: Optional[str] = None
589
) -> List["Hypergraph"]:
590
"""Get subgraphs for connected components."""
591
592
def components(
593
self,
594
edges: bool = False
595
) -> List[set]:
596
"""Alias for connected_components."""
597
598
def component_subgraphs(
599
self,
600
return_singletons: bool = False,
601
name: Optional[str] = None
602
) -> List["Hypergraph"]:
603
"""Alias for connected_component_subgraphs."""
604
```
605
606
### Distance and Diameter Analysis
607
608
Methods for computing distances and diameters in hypergraphs.
609
610
```python { .api }
611
def distance(
612
self,
613
source: Union[str, int],
614
target: Union[str, int],
615
s: int = 1
616
) -> int:
617
"""
618
Shortest path distance between two nodes.
619
620
Parameters:
621
- source: Source node UID
622
- target: Target node UID
623
- s: Distance level (paths through edges of size ≥ s+1)
624
625
Returns:
626
Shortest path distance
627
"""
628
629
def edge_distance(
630
self,
631
source: Union[str, int],
632
target: Union[str, int],
633
s: int = 1
634
) -> int:
635
"""Shortest path distance between two edges."""
636
637
def diameter(
638
self,
639
s: int = 1
640
) -> int:
641
"""
642
Maximum distance between any pair of nodes.
643
644
Parameters:
645
- s: Diameter level
646
647
Returns:
648
Hypergraph diameter
649
"""
650
651
def edge_diameter(
652
self,
653
s: int = 1
654
) -> int:
655
"""Maximum distance between any pair of edges."""
656
657
def node_diameters(
658
self,
659
s: int = 1
660
) -> Dict[Union[str, int], int]:
661
"""
662
All pairwise distances for nodes.
663
664
Parameters:
665
- s: Distance level
666
667
Returns:
668
Dictionary of node UIDs to their maximum distances
669
"""
670
671
def edge_diameters(
672
self,
673
s: int = 1
674
) -> Dict[Union[str, int], int]:
675
"""All pairwise distances for edges."""
676
```
677
678
### Advanced Operations
679
680
Additional methods for hypergraph analysis and manipulation.
681
682
```python { .api }
683
def equivalence_classes(
684
self,
685
edges: bool = True
686
) -> List[set]:
687
"""
688
Find equivalence classes of edges or nodes.
689
690
Parameters:
691
- edges: Find edge equivalence classes (True) or node classes (False)
692
693
Returns:
694
List of sets containing equivalent elements
695
"""
696
697
def get_linegraph(
698
self,
699
s: int = 1,
700
edges: bool = True
701
):
702
"""
703
Create line graph representation.
704
705
Parameters:
706
- s: Level for line graph construction
707
- edges: Create edge line graph (True) or node line graph (False)
708
709
Returns:
710
NetworkX graph representing the line graph
711
"""
712
713
def set_state(
714
self,
715
**kwargs
716
):
717
"""
718
Set hypergraph state with keyword arguments.
719
720
Parameters:
721
- **kwargs: State properties to set
722
"""
723
```
724
725
### Properties and Special Methods
726
727
Property accessors and special method operations.
728
729
```python { .api }
730
@property
731
def dataframe(self) -> DataFrame:
732
"""Access underlying dataframe representation."""
733
734
@property
735
def properties(self) -> "PropertyStore":
736
"""Access property store."""
737
738
def __len__(self) -> int:
739
"""Return number of nodes."""
740
741
def __iter__(self):
742
"""Iterate over nodes."""
743
744
def __contains__(self, item) -> bool:
745
"""Test if item is a node in the hypergraph."""
746
747
def __getitem__(self, node):
748
"""Access neighbors of a node."""
749
750
def __eq__(self, other) -> bool:
751
"""Test equality with another hypergraph."""
752
753
def __add__(self, other) -> "Hypergraph":
754
"""Addition operator (union)."""
755
756
def __sub__(self, other) -> "Hypergraph":
757
"""Subtraction operator (difference)."""
758
```