mlnlib 0.2.36__tar.gz → 0.2.38__tar.gz
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.
- {mlnlib-0.2.36/src/mlnlib.egg-info → mlnlib-0.2.38}/PKG-INFO +4 -4
- {mlnlib-0.2.36 → mlnlib-0.2.38}/README.md +3 -3
- {mlnlib-0.2.36 → mlnlib-0.2.38}/pyproject.toml +1 -1
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib/mln.py +108 -2
- {mlnlib-0.2.36 → mlnlib-0.2.38/src/mlnlib.egg-info}/PKG-INFO +4 -4
- {mlnlib-0.2.36 → mlnlib-0.2.38}/LICENSE.md +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/setup.cfg +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib/preparation.py +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib.egg-info/SOURCES.txt +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib.egg-info/dependency_links.txt +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib.egg-info/requires.txt +0 -0
- {mlnlib-0.2.36 → mlnlib-0.2.38}/src/mlnlib.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mlnlib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.38
|
|
4
4
|
Summary: Memory-efficient library for loading and working with large unweighted multilayer networks.
|
|
5
5
|
Author-email: Eszter Bokányi <e.bokanyi@uva.nl>
|
|
6
6
|
Project-URL: Homepage, https://github.com/popnet-io/popnet_mln
|
|
@@ -97,7 +97,7 @@ Example loadings:
|
|
|
97
97
|
```
|
|
98
98
|
# FROM FILES
|
|
99
99
|
# import custom class for the network from mln
|
|
100
|
-
import MultiLayeredNetwork
|
|
100
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
101
101
|
|
|
102
102
|
# read the whole network
|
|
103
103
|
popnet = MultiLayeredNetwork(
|
|
@@ -107,7 +107,7 @@ popnet = MultiLayeredNetwork(
|
|
|
107
107
|
|
|
108
108
|
# FROM MEMORY
|
|
109
109
|
# import custom class for the network
|
|
110
|
-
from mln import MultiLayeredNetwork
|
|
110
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
111
111
|
|
|
112
112
|
# read the whole network
|
|
113
113
|
popnet = MultiLayeredNetwork(
|
|
@@ -117,7 +117,7 @@ popnet = MultiLayeredNetwork(
|
|
|
117
117
|
|
|
118
118
|
# FROM LIBRARY
|
|
119
119
|
# import custom class for the network
|
|
120
|
-
from mln import MultiLayeredNetwork
|
|
120
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
121
121
|
|
|
122
122
|
# read the whole network
|
|
123
123
|
popnet = MultiLayeredNetwork(
|
|
@@ -77,7 +77,7 @@ Example loadings:
|
|
|
77
77
|
```
|
|
78
78
|
# FROM FILES
|
|
79
79
|
# import custom class for the network from mln
|
|
80
|
-
import MultiLayeredNetwork
|
|
80
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
81
81
|
|
|
82
82
|
# read the whole network
|
|
83
83
|
popnet = MultiLayeredNetwork(
|
|
@@ -87,7 +87,7 @@ popnet = MultiLayeredNetwork(
|
|
|
87
87
|
|
|
88
88
|
# FROM MEMORY
|
|
89
89
|
# import custom class for the network
|
|
90
|
-
from mln import MultiLayeredNetwork
|
|
90
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
91
91
|
|
|
92
92
|
# read the whole network
|
|
93
93
|
popnet = MultiLayeredNetwork(
|
|
@@ -97,7 +97,7 @@ popnet = MultiLayeredNetwork(
|
|
|
97
97
|
|
|
98
98
|
# FROM LIBRARY
|
|
99
99
|
# import custom class for the network
|
|
100
|
-
from mln import MultiLayeredNetwork
|
|
100
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
101
101
|
|
|
102
102
|
# read the whole network
|
|
103
103
|
popnet = MultiLayeredNetwork(
|
|
@@ -72,7 +72,7 @@ import networkx as nx
|
|
|
72
72
|
|
|
73
73
|
import gzip
|
|
74
74
|
|
|
75
|
-
from
|
|
75
|
+
from mlnlib.preparation import RawCSVtoMLN
|
|
76
76
|
|
|
77
77
|
from scipy.sparse import csr_matrix, save_npz, load_npz, eye, block_diag, kron
|
|
78
78
|
import json
|
|
@@ -1673,6 +1673,112 @@ class MultiLayerNetwork:
|
|
|
1673
1673
|
self.N = mask.sum()
|
|
1674
1674
|
self.A = self.A[mask,:][:,mask]
|
|
1675
1675
|
|
|
1676
|
+
def get_aggregated_network(self, aggregation_column=None, keep_layers = False, convert_A = "none"):
|
|
1677
|
+
"""
|
|
1678
|
+
Return an aggregated network over a certain column in self.nodes.
|
|
1679
|
+
|
|
1680
|
+
It looks at unique values in the column, and aggregates the edges for
|
|
1681
|
+
each unique value. The resulting network has as many nodes as there
|
|
1682
|
+
are unique values in the column. The edges are aggregated by counting all
|
|
1683
|
+
edges from all layers that go between the groups.
|
|
1684
|
+
|
|
1685
|
+
The resulting network is a MultiLayerNetwork object, but instead of the binary
|
|
1686
|
+
adjacency matrix, it has a weighted adjacency matrix, where the weights are
|
|
1687
|
+
the edge counts between the groups.
|
|
1688
|
+
|
|
1689
|
+
Parameters:
|
|
1690
|
+
-------------
|
|
1691
|
+
aggregation_column : string, default None
|
|
1692
|
+
the column in self.nodes based on which the edges should be aggregated
|
|
1693
|
+
-------------
|
|
1694
|
+
"""
|
|
1695
|
+
|
|
1696
|
+
if not aggregation_column in self.nodes.columns:
|
|
1697
|
+
raise ValueError(f"Column {aggregation_column} not found in self.nodes. Possible candidates are: ", self.nodes.columns)
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
if self.use_polars:
|
|
1701
|
+
mask = self.nodes["active"] & self.nodes[aggregation_column].is_not_null()
|
|
1702
|
+
affil_edgelist = list(zip(self.nodes["label"].filter(mask), self.nodes[aggregation_column].filter(mask)))
|
|
1703
|
+
else:
|
|
1704
|
+
mask = self.nodes["active"] & (~pd.isnull(self.nodes[aggregation_column]))
|
|
1705
|
+
affil_edgelist = list(zip(self.nodes["label"][mask], self.nodes[aggregation_column][mask]))
|
|
1706
|
+
|
|
1707
|
+
self.create_affiliation_matrix(aggregation_column,affil_edgelist)
|
|
1708
|
+
|
|
1709
|
+
if convert_A == "boolean":
|
|
1710
|
+
G = self.affiliation_matrix[aggregation_column]["A"].T * self.A.sign() * self.affiliation_matrix[aggregation_column]["A"]
|
|
1711
|
+
elif convert_A == "multiplexity":
|
|
1712
|
+
A = deepcopy(self.A)
|
|
1713
|
+
# create lookup table for mapping binary values to number of layers / multiplexity
|
|
1714
|
+
lookup = {}
|
|
1715
|
+
for num in np.unique(A.data):
|
|
1716
|
+
lookup[num] = bin(num).count("1")
|
|
1717
|
+
# apply lookup table
|
|
1718
|
+
A.data = np.array([lookup[x] for x in A.data])
|
|
1719
|
+
G = self.affiliation_matrix[aggregation_column]["A"].T * A * self.affiliation_matrix[aggregation_column]["A"]
|
|
1720
|
+
elif convert_A == "none":
|
|
1721
|
+
G = self.affiliation_matrix[aggregation_column]["A"].T * self.A * self.affiliation_matrix[aggregation_column]["A"]
|
|
1722
|
+
else:
|
|
1723
|
+
ValueError("Invalid value for convert_A, please choose from none, booelan, or multiplexity.")
|
|
1724
|
+
uniques = [self.affiliation_matrix[aggregation_column]["column_id_to_label"][i] for i in range(self.affiliation_matrix[aggregation_column]["M"])]
|
|
1725
|
+
if 'weight' not in self.nodes.columns:
|
|
1726
|
+
# count occurrences in each aggregation group
|
|
1727
|
+
grp_counts = self.affiliation_matrix[aggregation_column]["A"].sum(axis=0).tolist()[0]
|
|
1728
|
+
else:
|
|
1729
|
+
# sum up previous weights
|
|
1730
|
+
grp_counts = self.nodes[mask].groupby(aggregation_column)['weight'].sum().loc[uniques]
|
|
1731
|
+
|
|
1732
|
+
if self.use_polars:
|
|
1733
|
+
nodes_selected = pl.DataFrame({
|
|
1734
|
+
'label' : uniques,
|
|
1735
|
+
'weight' : grp_counts,
|
|
1736
|
+
"id" : [i for i in range(self.affiliation_matrix[aggregation_column]["M"])]
|
|
1737
|
+
}
|
|
1738
|
+
)
|
|
1739
|
+
else:
|
|
1740
|
+
nodes_selected = pd.DataFrame(data={
|
|
1741
|
+
'label' : uniques,
|
|
1742
|
+
'weight' : grp_counts,
|
|
1743
|
+
"id" : [i for i in range(self.affiliation_matrix[aggregation_column]["M"])]
|
|
1744
|
+
}
|
|
1745
|
+
)
|
|
1746
|
+
|
|
1747
|
+
# add data related to particular aggregation level
|
|
1748
|
+
if self.use_polars:
|
|
1749
|
+
aggregation_nodes = self.nodes.select([c for c in self.nodes.columns if aggregation_column.split('_')[0] in c]).groupby([aggregation_column]).first()
|
|
1750
|
+
nodes_selected = nodes_selected.join(aggregation_nodes, left_on=['label'], right_on=[aggregation_column], how='left')
|
|
1751
|
+
else:
|
|
1752
|
+
aggregation_nodes = self.nodes.groupby([aggregation_column]).head(1)[[c for c in self.nodes.columns if aggregation_column.split('_')[0] in c]]
|
|
1753
|
+
nodes_selected = nodes_selected.merge(aggregation_nodes, left_on=['label'], right_on=[aggregation_column], how='left')
|
|
1754
|
+
|
|
1755
|
+
f = MultiLayerNetwork(
|
|
1756
|
+
edges = G.tocsr(),
|
|
1757
|
+
nodes = nodes_selected,
|
|
1758
|
+
**self._to_pass
|
|
1759
|
+
)
|
|
1760
|
+
|
|
1761
|
+
# this is only providing raw counts for all selected layers
|
|
1762
|
+
# TODO: it would be more elegant to keep layers!
|
|
1763
|
+
selection_layers = pd.DataFrame(data={'layer' : 1, 'label' : 'count', 'label_long' : 'count_'+convert_A, 'layer' : 'count', 'binary' : 1}, index=[0])
|
|
1764
|
+
selection_layers_dict = {
|
|
1765
|
+
'binary_to_layer': {1 : 1},
|
|
1766
|
+
'binary_to_layer' : {1 : 'count'},
|
|
1767
|
+
'layer_to_layer' : {1 : 'count'},
|
|
1768
|
+
'layer_to_binary' : {1 : 1},
|
|
1769
|
+
'layer_to_binary' : {'count' : 1},
|
|
1770
|
+
'layer_to_layer' : {'count' : 1}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
f.layers = selection_layers
|
|
1774
|
+
f._layer_conversion_dict = selection_layers_dict
|
|
1775
|
+
# The nodes have changed, therefore new mappings for to_nid and to_label are passed.
|
|
1776
|
+
f._map_label_to_id = dict(zip(f.nodes["label"],f.nodes["id"]))
|
|
1777
|
+
f._map_id_to_label = dict(zip(f.nodes["id"],f.nodes["label"]))
|
|
1778
|
+
f.adjacency_element = "weight"
|
|
1779
|
+
|
|
1780
|
+
return f
|
|
1781
|
+
|
|
1676
1782
|
|
|
1677
1783
|
|
|
1678
1784
|
|
|
@@ -1681,4 +1787,4 @@ class MultiLayerNetwork:
|
|
|
1681
1787
|
|
|
1682
1788
|
|
|
1683
1789
|
|
|
1684
|
-
|
|
1790
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mlnlib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.38
|
|
4
4
|
Summary: Memory-efficient library for loading and working with large unweighted multilayer networks.
|
|
5
5
|
Author-email: Eszter Bokányi <e.bokanyi@uva.nl>
|
|
6
6
|
Project-URL: Homepage, https://github.com/popnet-io/popnet_mln
|
|
@@ -97,7 +97,7 @@ Example loadings:
|
|
|
97
97
|
```
|
|
98
98
|
# FROM FILES
|
|
99
99
|
# import custom class for the network from mln
|
|
100
|
-
import MultiLayeredNetwork
|
|
100
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
101
101
|
|
|
102
102
|
# read the whole network
|
|
103
103
|
popnet = MultiLayeredNetwork(
|
|
@@ -107,7 +107,7 @@ popnet = MultiLayeredNetwork(
|
|
|
107
107
|
|
|
108
108
|
# FROM MEMORY
|
|
109
109
|
# import custom class for the network
|
|
110
|
-
from mln import MultiLayeredNetwork
|
|
110
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
111
111
|
|
|
112
112
|
# read the whole network
|
|
113
113
|
popnet = MultiLayeredNetwork(
|
|
@@ -117,7 +117,7 @@ popnet = MultiLayeredNetwork(
|
|
|
117
117
|
|
|
118
118
|
# FROM LIBRARY
|
|
119
119
|
# import custom class for the network
|
|
120
|
-
from mln import MultiLayeredNetwork
|
|
120
|
+
from mlnlib.mln import MultiLayeredNetwork
|
|
121
121
|
|
|
122
122
|
# read the whole network
|
|
123
123
|
popnet = MultiLayeredNetwork(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|