title: Networkx: how to combine edges together with condition?
body: <p>I'm working with Open Street Data that I've enriched and am modeling through NetworkX.
  However, there is a very large number of nodes that just exist to design the edges' curves, as they've only got two edges.</p>
  <p>Therefore, I'd need to simplify the grah by aggregating edges connecting such nodes to each other, while keeping the attributes of the aggregated edges.</p>
  <p>Here's a reproducible example:</p>
  <pre><code>import networkx as nx
  from shapely.geometry import LineString, Point
  
  G = nx.Graph()
  G.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
  G.add_edges_from([(1, 2, {'highway': 'primary', 'speed_kph': 90, 'slope': 1.2,
                            'geometry': LineString([Point(3.013832,42.785837), Point(3.010505, 42.787605)])}),
                    (2, 3, {'highway': 'primary', 'speed_kph': 70, 'slope': 0.8,
                            'geometry': LineString([Point(3.010505, 42.787605), Point(3.006227, 42.789605)])}),
                    (3, 4, {'highway': 'primary', 'speed_kph': 50, 'slope': -0.1,
                            'geometry': LineString([Point(3.006227, 42.789605), Point(3.001030, 42.789721)])}),
                    (4, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': 3.1,
                            'geometry': LineString([Point(3.001030, 42.789721), Point(3.000998, 42.79321)])}),
                    (5, 6, {'highway': 'primary', 'speed_kph': 70, 'slope': -1.3,
                            'geometry': LineString([Point(3.000998, 42.79321), Point(2.995483, 42.795675)])}),
                    (4, 10, {'highway': 'tertiary', 'speed_kph': 50, 'slope': 3.7,
                            'geometry': LineString([Point(3.001030, 42.789721), Point(2.998273, 42.787303)])}),
                    (10, 11, {'highway': 'tertiary', 'speed_kph': 30, 'slope': 2.9,
                            'geometry': LineString([Point(2.998273, 42.787303), Point(2.995231, 42.784279)])}),
                    (3, 7, {'highway': 'secondary', 'speed_kph': 50, 'slope': 5.6,
                            'geometry': LineString([Point(3.006227, 42.789605), Point(3.009407, 42.791873)])}),
                    (7, 8, {'highway': 'secondary', 'speed_kph': 50, 'slope': 6.4,
                            'geometry': LineString([Point(3.009407, 42.791873), Point(3.009217, 42.794710)])}),
                    (8, 9, {'highway': 'secondary', 'speed_kph': 50, 'slope': -4.3,
                            'geometry': LineString([Point(3.009217, 42.794710), Point(3.005858, 42.796036)])}),
                    (9, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': -7.2,
                            'geometry': LineString([Point(3.005858, 42.796036), Point(3.000998, 42.79321)])})])
  
  nx.draw(G, with_labels=True)
  plt.show()
  </code></pre>
  <p><a href="https://i.stack.imgur.com/zrsSF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zrsSF.png" alt="example_graph" /></a></p>
  <p>As you can see, edges (1,2) and (2,3) could be aggregated together, as well as (4,10) and (10,11), and even (3,7), (7,8), (8,9), (9,5) could be summarized as a single edge.</p>
  <p>While aggregating, however, I would not like to lose the <code>speed_kph</code> and <code>slope</code> attributes, and chose to keep the mean of the edges combined.
  As for the geometry, I'd like to combine the linestrings. So the resulting network should be as follows</p>
  <pre><code>import numpy as np
  from shapely.ops import linemerge
  
  new_G = nx.Graph()
  new_G.add_nodes_from([1, 3, 4, 5, 6, 11])
  new_G.add_edges_from([(1, 3, {'highway': 'primary', 'speed_kph': np.mean([90, 70]), 'slope': np.mean([1.2, 0.8]),
                                'geometry': linemerge([LineString([Point(3.013832,42.785837), Point(3.010505, 42.787605)]),
                                                      LineString([Point(3.010505, 42.787605), Point(3.006227, 42.789605)])])}),
                        (3, 4, {'highway': 'primary', 'speed_kph': 50, 'slope': -0.1,
                                'geometry': LineString([Point(3.006227, 42.789605), Point(3.001030, 42.789721)])}),
                        (4, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': 3.1,
                                'geometry': LineString([Point(3.001030, 42.789721), Point(3.000998, 42.79321)])}),
                        (5, 6, {'highway': 'primary', 'speed_kph': 70, 'slope': -1.3,
                                'geometry': LineString([Point(3.000998, 42.79321), Point(2.995483, 42.795675)])}),
                        (4, 11, {'highway': 'primary', 'speed_kph': np.mean([50, 30]), 'slope': np.mean([3.7, 2.9]),
                                'geometry': linemerge([LineString([Point(3.001030, 42.789721), Point(2.998273, 42.787303)]),
                                                      LineString([Point(2.998273, 42.787303), Point(2.995231, 42.784279)])])}),
                        (3, 5, {'highway': 'primary', 'speed_kph': np.mean([50, 50, 50, 50]), 'slope': np.mean([5.6, 6.4, -4.3, -7.2]),
                                'geometry': linemerge([LineString([Point(3.006227, 42.789605), Point(3.009407, 42.791873)]),
                                                      LineString([Point(3.009407, 42.791873), Point(3.009217, 42.794710)]),
                                                      LineString([Point(3.009217, 42.794710), Point(3.005858, 42.796036)]),
                                                      LineString([Point(3.005858, 42.796036), Point(3.000998, 42.79321)])])}),
                        ])
  
  nx.draw(new_G, with_labels=True)
  plt.show()
  </code></pre>
  <p><a href="https://i.stack.imgur.com/indFt.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/indFt.png" alt="Simplified graph" /></a></p>
  <p>Does anybody know how I could do that?</p>
  <p>Of course, the idea would be to detect the combinable edges automatically (possibly using a threshold on the <code>degree</code>) as I'm working with a number of edges much higher than in that toy example and cannot do it manually.</p>