Related
I want to connect eulerian cycles into longer ones without exceed a value.
So, I have this eulerian cycles and their length in a list. The maximal length of a cycle can be for example 500. The length of all cycles added up is 6176.778566350282. By connecting them cleverly together there could be probably only 13 or 14 cycles. But I don't really know how I could do that. I tried to just add one cycle to another but there I got 21 cycles out. The problem is that if you have a cycle of these numbers for example: [8, 21, 9, 22, 8, 23, 9, 24, 8] and you want to integrate this cycle [10, 11, 12, 10] it will not work because in the first cycle there is no edge of the number 10. I just started then a new cycle with this numbers [10, 11, 12, 10] and saved [8, 21, 9, 22, 8, 23, 9, 24, 8] as one of the 21 result cycles. But with this method I don't really get a good result. What would be a cleverer way to solve this problem?
This is an example how the list of the short eulerian cycles looks like:
[([0, 1, 2, 0], 36.36630772776802), ([0, 3, 1, 4, 0], 93.83277865587606), ([0, 5, 1, 6, 0], 45.79353710664728), ([0, 7, 1, 8, 0], 49.60782827778143), ([0, 9, 1, 10, 0], 73.2674533926481), ([0, 11, 1, 12, 0], 75.52124688926921), ([0, 13, 1, 14, 0], 57.88021234723078), ([0, 15, 1, 16, 0], 62.21469065955568), ([0, 17, 1, 18, 0], 81.43809748917617), ([0, 19, 1, 20, 0], 98.88867905572438), ([0, 21, 1, 22, 0], 95.3596513800762), ([0, 23, 1, 24, 0], 116.15359042770964), ([2, 3, 4, 2], 49.106297391220245), ([2, 5, 3, 6, 2], 71.5422470782724), ([2, 7, 3, 8, 2], 50.237654764168), ([2, 9, 3, 10, 2], 71.36355688043689), ([2, 11, 3, 12, 2], 44.474596239420634), ([2, 13, 3, 14, 2], 103.42527218232905), ([2, 15, 3, 16, 2], 65.92444557445982), ([2, 17, 3, 18, 2], 83.30561323888043), ([2, 19, 3, 20, 2], 144.20150278029047), ([2, 21, 3, 22, 2], 131.70030082856), ([2, 23, 3, 24, 2], 141.63032737825358), ([4, 5, 6, 4], 42.10300780814433), ([4, 7, 5, 8, 4], 88.13162862262575), ([4, 9, 5, 10, 4], 29.40312423743285), ([4,
11, 5, 12, 4], 35.06685249446684), ([4, 13, 5, 14, 4], 83.54113932583394), ([4, 15, 5, 16, 4], 57.669814210895076), ([4, 17, 5, 18, 4], 85.16088821443248), ([4, 19, 5, 20, 4], 115.83839679838714), ([4, 21, 5, 22, 4], 96.32509817470469), ([4, 23, 5, 24, 4], 95.72504474795447), ([6, 7, 8, 6], 39.680511478789455), ([6, 9, 7, 10, 6], 78.55998969220359), ([6, 11, 7, 12, 6], 75.38181527864062), ([6, 13, 7, 14, 6], 65.59514045044449), ([6, 15, 7, 16, 6], 64.00893982862813), ([6, 17, 7, 18, 6], 82.99423226082924), ([6, 19, 7, 20, 6], 107.80803412093549), ([6, 21, 7, 22, 6], 104.34384551877056), ([6, 23, 7, 24, 6], 125.5684717784), ([8, 9, 10, 8], 52.130784276071026), ([8, 11, 9, 12, 8], 60.084249983353345), ([8, 13, 9, 14,
8], 80.8264707041123), ([8, 15, 9, 16, 8], 56.067658306081576), ([8, 17, 9, 18, 8], 87.79739969269264), ([8, 19, 9, 20, 8], 115.04095207094785),
([8, 21, 9, 22, 8], 100.28892183336735), ([8, 23, 9, 24, 8], 107.98171312085222), ([10, 11, 12, 10], 18.073592581964586), ([10, 13, 11, 14, 10],
86.59048377734861), ([10, 15, 11, 16, 10], 53.62896051047471), ([10, 17, 11, 18, 10], 79.42707393175432), ([10, 19, 11, 20, 10], 121.75438335508098), ([10, 21, 11, 22, 10], 103.13320830479722), ([10, 23, 11, 24, 10], 104.67092453129686), ([12, 13, 14, 12], 65.01056040398879), ([12, 15, 13, 16, 12], 73.92038351218434), ([12, 17, 13, 18, 12], 75.85986620162797), ([12, 19, 13, 20, 12], 99.9668143111241), ([12, 21, 13, 22, 12], 97.01425784207544), ([12, 23, 13, 24, 12], 113.28618776429398), ([14, 15, 16, 14], 53.12806382231952), ([14, 17, 15, 18, 14], 83.32318283097464), ([14,
19, 15, 20, 14], 59.489711796339975), ([14, 21, 15, 22, 14], 49.93204117686305), ([14, 23, 15, 24, 14], 59.39628730132421), ([16, 17, 18, 16], 76.30230372794964), ([16, 19, 17, 20, 16], 151.38369644764225), ([16, 21, 17, 22, 16], 137.27131752575687), ([16, 23, 17, 24, 16], 146.11467181532439), ([18, 19, 20, 18], 28.731124011957917), ([18, 21, 19, 22, 18], 51.78367537918862), ([18, 23, 19, 24, 18], 86.45013419422762), ([20, 21, 22,
20], 39.010097887844154), ([20, 23, 21, 24, 20], 63.48159687540681), ([22, 23, 24, 22], 22.283951753399037)]
I designed an elaborate branch-and-price scheme and then realized that it probably wouldn’t work well. Here’s a much simpler local search that achieves 14 cycles on your sample input.
from collections import defaultdict
from itertools import combinations
import random
# pip3 install networkx if necessary.
import networkx as nx
# The input consists of the variables maximum_length and cycles.
maximum_length = 500
cycles = [
([0, 1, 2, 0], 36.36630772776802),
([0, 3, 1, 4, 0], 93.83277865587606),
([0, 5, 1, 6, 0], 45.79353710664728),
([0, 7, 1, 8, 0], 49.60782827778143),
([0, 9, 1, 10, 0], 73.2674533926481),
([0, 11, 1, 12, 0], 75.52124688926921),
([0, 13, 1, 14, 0], 57.88021234723078),
([0, 15, 1, 16, 0], 62.21469065955568),
([0, 17, 1, 18, 0], 81.43809748917617),
([0, 19, 1, 20, 0], 98.88867905572438),
([0, 21, 1, 22, 0], 95.3596513800762),
([0, 23, 1, 24, 0], 116.15359042770964),
([2, 3, 4, 2], 49.106297391220245),
([2, 5, 3, 6, 2], 71.5422470782724),
([2, 7, 3, 8, 2], 50.237654764168),
([2, 9, 3, 10, 2], 71.36355688043689),
([2, 11, 3, 12, 2], 44.474596239420634),
([2, 13, 3, 14, 2], 103.42527218232905),
([2, 15, 3, 16, 2], 65.92444557445982),
([2, 17, 3, 18, 2], 83.30561323888043),
([2, 19, 3, 20, 2], 144.20150278029047),
([2, 21, 3, 22, 2], 131.70030082856),
([2, 23, 3, 24, 2], 141.63032737825358),
([4, 5, 6, 4], 42.10300780814433),
([4, 7, 5, 8, 4], 88.13162862262575),
([4, 9, 5, 10, 4], 29.40312423743285),
([4, 11, 5, 12, 4], 35.06685249446684),
([4, 13, 5, 14, 4], 83.54113932583394),
([4, 15, 5, 16, 4], 57.669814210895076),
([4, 17, 5, 18, 4], 85.16088821443248),
([4, 19, 5, 20, 4], 115.83839679838714),
([4, 21, 5, 22, 4], 96.32509817470469),
([4, 23, 5, 24, 4], 95.72504474795447),
([6, 7, 8, 6], 39.680511478789455),
([6, 9, 7, 10, 6], 78.55998969220359),
([6, 11, 7, 12, 6], 75.38181527864062),
([6, 13, 7, 14, 6], 65.59514045044449),
([6, 15, 7, 16, 6], 64.00893982862813),
([6, 17, 7, 18, 6], 82.99423226082924),
([6, 19, 7, 20, 6], 107.80803412093549),
([6, 21, 7, 22, 6], 104.34384551877056),
([6, 23, 7, 24, 6], 125.5684717784),
([8, 9, 10, 8], 52.130784276071026),
([8, 11, 9, 12, 8], 60.084249983353345),
([8, 13, 9, 14, 8], 80.8264707041123),
([8, 15, 9, 16, 8], 56.067658306081576),
([8, 17, 9, 18, 8], 87.79739969269264),
([8, 19, 9, 20, 8], 115.04095207094785),
([8, 21, 9, 22, 8], 100.28892183336735),
([8, 23, 9, 24, 8], 107.98171312085222),
([10, 11, 12, 10], 18.073592581964586),
([10, 13, 11, 14, 10], 86.59048377734861),
([10, 15, 11, 16, 10], 53.62896051047471),
([10, 17, 11, 18, 10], 79.42707393175432),
([10, 19, 11, 20, 10], 121.75438335508098),
([10, 21, 11, 22, 10], 103.13320830479722),
([10, 23, 11, 24, 10], 104.67092453129686),
([12, 13, 14, 12], 65.01056040398879),
([12, 15, 13, 16, 12], 73.92038351218434),
([12, 17, 13, 18, 12], 75.85986620162797),
([12, 19, 13, 20, 12], 99.9668143111241),
([12, 21, 13, 22, 12], 97.01425784207544),
([12, 23, 13, 24, 12], 113.28618776429398),
([14, 15, 16, 14], 53.12806382231952),
([14, 17, 15, 18, 14], 83.32318283097464),
([14, 19, 15, 20, 14], 59.489711796339975),
([14, 21, 15, 22, 14], 49.93204117686305),
([14, 23, 15, 24, 14], 59.39628730132421),
([16, 17, 18, 16], 76.30230372794964),
([16, 19, 17, 20, 16], 151.38369644764225),
([16, 21, 17, 22, 16], 137.27131752575687),
([16, 23, 17, 24, 16], 146.11467181532439),
([18, 19, 20, 18], 28.731124011957917),
([18, 21, 19, 22, 18], 51.78367537918862),
([18, 23, 19, 24, 18], 86.45013419422762),
([20, 21, 22, 20], 39.010097887844154),
([20, 23, 21, 24, 20], 63.48159687540681),
([22, 23, 24, 22], 22.283951753399037),
]
for cycle, length in cycles:
assert cycle[0] == cycle[-1]
assert 0 <= length <= maximum_length
# Two cycles can be merged if and only if there exists a vertex that they have
# in common. Compute the graph where each cycle is a node and each pair of
# cycles that can be merged is an edge. A set of cycles can be merged if and
# only if the total length does not exceed the maximum and the corresponding set
# of nodes induces a connected subgraph.
inverted_index = defaultdict(list)
for i, (cycle, length) in enumerate(cycles):
for v in set(cycle):
inverted_index[v].append(i)
cycle_graph = nx.Graph()
for i, (cycle, length) in enumerate(cycles):
cycle_graph.add_node(i, length=length)
for posting_list in inverted_index.values():
for e in combinations(posting_list, 2):
cycle_graph.add_edge(*e)
lengths = [round(length * 2**40) / 2**40 for (cycle, length) in cycles]
# We want to find the smallest partition of cycles into mergeable parts. This
# code implements a greedy local search. Initialize the partition where every
# cycle is in its own part. For some number of steps, move one cycle to another
# part, respecting the connectivity constraint.
def make_part_graph(part):
part_graph = cycle_graph.subgraph(part)
return nx.Graph(
part_graph,
can_move=set(part_graph.nodes()) - set(nx.articulation_points(part_graph)),
length=sum(lengths[i] for i in part_graph.nodes()),
)
def merge_cycles(indexes):
g = nx.DiGraph()
for i in indexes:
cycle, length = cycles[i]
for j in range(1, len(cycle)):
g.add_edge(cycle[j - 1], cycle[j])
cycle = []
for u, v in nx.eulerian_circuit(g):
if not cycle:
cycle.append(u)
cycle.append(v)
return cycle, sum(lengths[i] for i in indexes)
labels = list(range(len(cycles)))
cycle_subgraphs = {i: make_part_graph({i}) for i in range(len(cycles))}
for step in range(10000):
moves = []
for tail, cycle_subgraph in cycle_subgraphs.items():
for i in cycle_subgraph.graph["can_move"]:
for j in cycle_graph.neighbors(i):
head = labels[j]
if (
head != tail
and cycle_subgraphs[head].graph["length"] + lengths[i]
<= maximum_length
):
moves.append((i, tail, head))
i, tail, head = random.choice(moves)
labels[i] = head
cycle_subgraphs[tail] = make_part_graph(set(cycle_subgraphs[tail].nodes()) - {i})
cycle_subgraphs[head] = make_part_graph(set(cycle_subgraphs[head].nodes()) | {i})
for cycle_subgraph in cycle_subgraphs.values():
part = sorted(cycle_subgraph.nodes())
if not part:
continue
print(*merge_cycles(part))
Output:
[0, 23, 11, 24, 8, 23, 9, 3, 10, 2, 9, 24, 10, 23, 1, 24, 0, 21, 1, 22, 0] 495.5294363403709
[0, 19, 17, 20, 16, 19, 22, 18, 21, 3, 22, 2, 21, 19, 1, 20, 0, 5, 1, 6, 0] 479.5498888177626
[6, 23, 17, 24, 16, 10, 15, 11, 14, 10, 13, 11, 16, 23, 7, 24, 6] 411.90258788154733
[0, 9, 22, 8, 21, 9, 18, 16, 17, 18, 8, 17, 9, 16, 8, 15, 9, 12, 8, 6, 7, 8, 11, 9, 1, 10, 0] 493.488498414883
[2, 5, 3, 6, 19, 9, 10, 8, 9, 20, 23, 21, 24, 20, 8, 19, 7, 20, 6, 2] 410.00361442163285
[0, 7, 22, 6, 21, 7, 16, 12, 15, 20, 14, 19, 11, 20, 10, 19, 15, 13, 16, 6, 15, 7, 1, 8, 0] 473.1250922887857
[0, 13, 1, 14, 0, 11, 22, 10, 21, 11, 5, 12, 4, 11, 3, 12, 2, 11, 1, 12, 0, 1, 2, 0] 352.442424002953
[0, 3, 1, 4, 23, 15, 24, 14, 23, 5, 24, 4, 7, 5, 8, 4, 0] 337.0857393277802
[4, 21, 13, 7, 14, 8, 13, 9, 14, 6, 13, 22, 23, 24, 22, 20, 21, 22, 12, 21, 5, 22, 4, 9, 5, 10, 4] 430.458141050015
[2, 23, 3, 24, 2, 13, 3, 14, 2, 7, 12, 6, 11, 7, 10, 6, 4, 5, 6, 9, 7, 3, 8, 2] 491.33806710373847
[0, 15, 22, 14, 21, 15, 5, 20, 12, 10, 11, 12, 19, 13, 20, 4, 19, 5, 16, 4, 15, 1, 16, 0] 403.69534973878945
[0, 17, 22, 16, 21, 17, 11, 18, 19, 3, 20, 2, 19, 20, 18, 10, 17, 1, 18, 0] 471.0691157389365
[2, 15, 16, 14, 4, 13, 24, 18, 23, 19, 24, 12, 23, 13, 5, 14, 15, 3, 16, 2, 3, 4, 2] 451.43626807235523
[2, 17, 15, 18, 14, 12, 13, 14, 17, 13, 18, 12, 17, 7, 18, 6, 17, 5, 18, 4, 17, 3, 18, 2] 475.65434315073435
I am working on extracting people and tasks from texts (multiple sentences) and need a way to resolve coreferencing. I found this model, and it seems very promising, but once I installed the required libraries allennlp and allennlp_models and testing the model out for myself I got:
Script:
predictor = Predictor.from_path("https://storage.googleapis.com/allennlp-public-models/coref-spanbert-large-2021.03.10.tar.gz")
prediction = predictor.predict(
document="Paul Allen was born on January 21, 1953, in Seattle, Washington, to Kenneth Sam Allen and Edna Faye Allen. Allen attended Lakeside School, a private school in Seattle, where he befriended Bill Gates, two years younger, with whom he shared an enthusiasm for computers.")
print(prediction)
Output:
{'top_spans': [[0, 1], [3, 3], [5, 8], [5, 14], [8, 8], [11, 13], [11, 14], [13, 13], [16, 18], [16, 22], [20, 22], [24, 24], [26, 52], [33, 33], [36, 36], [37, 37], [38, 52], [41, 42], [47, 47], [48, 48], [49, 52]],
'antecedent_indices': [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]],
'predicted_antecedents': [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 5, 11, -1, -1, -1, 11, -1, -1],
'document': ['Paul', 'Allen', 'was', 'born', 'on', 'January', '21', ',', '1953', ',', 'in', 'Seattle', ',', 'Washington', ',', 'to', 'Kenneth', 'Sam', 'Allen', 'and', 'Edna', 'Faye', 'Allen', '.', 'Allen', 'attended', 'Lakeside', 'School', ',', 'a', 'private', 'school', 'in', 'Seattle', ',', 'where', 'he', 'befriended', 'Bill', 'Gates', ',', 'two', 'years', 'younger', ',', 'with', 'whom', 'he', 'shared', 'an', 'enthusiasm', 'for', 'computers', '.'],
'clusters': [[[0, 1], [24, 24], [36, 36], [47, 47]], [[11, 13], [33, 33]]]}
I'm having trouble interpreting the format of this output. I was expecting something like
{entity_0_spans: [LIST_OF_INDEX_TUPLES], # Paul Allen in this example
entity_1_spans: [LIST_OF_INDEX_TUPLES], # Seattle in this example
...}
or something that more closely resembles the visualisation available on the demo page:
I've looked through https://demo.allennlp.org/coreference-resolution but couldn't find a breakdown of how to use the model output yet - can anyone suggest some resources that will help me? Any pointers are much appreciated!
The information you are looking for is in 'clusters', where each list corresponds to an entity. Within each entity list, you will find the mentions referring to the same entity. The number are indices that mark the beginning and ending of each coreferential mention. E.g. Paul Allen [0,1] and Allen [24, 24].
This is the code I am working with currently and that I want to create a multidimensional array of the year 2020 using all the months:
import calendar
a = calendar.monthcalendar(2020, 1), calendar.monthcalendar(2020, 2)
print(a)
"""
print(calendar.monthcalendar(2020, 2))
print(calendar.monthcalendar(2020, 3))
print(calendar.monthcalendar(2020, 4))
print(calendar.monthcalendar(2020, 5))
print(calendar.monthcalendar(2020, 6))
print(calendar.monthcalendar(2020, 7))
print(calendar.monthcalendar(2020, 8))
print(calendar.monthcalendar(2020, 9))
print(calendar.monthcalendar(2020, 10))
print(calendar.monthcalendar(2020, 11))
print(calendar.monthcalendar(2020, 12))
"""
Use a list-comprehension to get all the weeks of 2020 using the monthcalendar of Python's calendarmodule
https://docs.python.org/3/library/calendar.html
(Returns a matrix representing a month’s calendar. Each row represents a week; days outside of the month a represented by zeros. Each week begins with Monday)
from calendar import monthcalendar
weeks_2020 = [monthcalendar(2020, i) for i in range(1, 13)]
for week in weeks_2020:
print(week)
Result:
[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 0, 0]]
[[0, 0, 0, 0, 0, 1, 2], [3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 0]]
[[0, 0, 0, 0, 0, 0, 1], [2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22], [23, 24, 25, 26, 27, 28, 29], [30, 31, 0, 0, 0, 0, 0]]
[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 0, 0, 0]]
[[0, 0, 0, 0, 1, 2, 3], [4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31]]
[[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14], [15, 16, 17, 18, 19, 20, 21], [22, 23, 24, 25, 26, 27, 28], [29, 30, 0, 0, 0, 0, 0]]
[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 0, 0]]
[[0, 0, 0, 0, 0, 1, 2], [3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30], [31, 0, 0, 0, 0, 0, 0]]
[[0, 1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 0, 0, 0, 0]]
[[0, 0, 0, 1, 2, 3, 4], [5, 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17, 18], [19, 20, 21, 22, 23, 24, 25], [26, 27, 28, 29, 30, 31, 0]]
[[0, 0, 0, 0, 0, 0, 1], [2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22], [23, 24, 25, 26, 27, 28, 29], [30, 0, 0, 0, 0, 0, 0]]
[[0, 1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 31, 0, 0, 0]]
Given a numpy array
import numpy as np
a = np.arange(4*7).reshape([4, 7])
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
I can apply slicing to swap the second and third columns by:
a[:, [0, 2, 1, 3, 4, 5, 6]]
array([[ 0, 2, 1, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
But, can I use slices to swap the second and third columns for all rows but the first one? The expected output would be:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
For in-situ edit, we can use flipping after slicing out the two columns -
a[1:,1:3] = a[1:,2:0:-1]
Sample run -
In [556]: a = np.arange(4*7).reshape([4, 7])
In [557]: a
Out[557]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
In [559]: a[1:,1:3] = a[1:,2:0:-1]
In [560]: a
Out[560]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
For columns that are two-step apart, use a stepsize of 2 to assign (LHS) and -2 to select (RHS). Hence, for column IDs 1 & 3 -
In [577]: a = np.arange(4*7).reshape([4, 7])
In [578]: a
Out[578]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
In [579]: a[1:,1:4:2] = a[1:,3:0:-2]
In [580]: a
Out[580]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 10, 9, 8, 11, 12, 13],
[14, 17, 16, 15, 18, 19, 20],
[21, 24, 23, 22, 25, 26, 27]])
Another method would be with explicit column numbered indexing -
a[1:,[1,2]] = a[1:,[2,1]]
Note that this creates a copy with a[1:,[2,1]] and as such would be less memory efficient than the first method.
I have used the calendar.py module in Python:
for day in list(calendar.monthcalendar(2017,calmonth)):
print(day)
to create a matrix for a month as:
[0, 0, 0, 0, 0, 0, 1]
[2, 3, 4, 5, 6, 7, 8]
[9, 10, 11, 12, 13, 14, 15]
[16, 17, 18, 19, 20, 21, 22]
[23, 24, 25, 26, 27, 28, 29]
[30, 31, 0, 0, 0, 0, 0]
I want to transform this into a simple list like:
(1,2,3,4....31)
This would mean getting rid of the zeroes and transforming the matrix into a list.
I have tried first turning it into an array with numpy:
for day in list(calendar.monthcalendar(2017,calmonth)):
print(day)
dayarray = np.squeeze(np.asarray(day))
print(dayarray)
But no other numpy formulas for getting rid of zeroes or transforming into a list seem to work.
No need to use monthcalendar, there are calendar.py functions much better suited for your needs:
_, ndays = calendar.monthrange(2017, 12)
l = list(range(1, ndays+1))
print(l)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
You can extract it with two for loops:
my_matrix = [[0, 0, 0, 0, 0, 0, 1],
[2, 3, 4, 5, 6, 7, 8],
[9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22],
[23, 24, 25, 26, 27, 28, 29],
[30, 31, 0, 0, 0, 0, 0]]
my_list = []
for array in my_matrix:
for i in array:
if i>0:
my_list.append(i)
print(my_list)