Issue
The problem: I am trying to generate m vectors of n elements, based on a "packaged", or shorter, master vector, V, that is shorter than m x n, and a length n boolean vector that determines how elements are repeated. (Vectors explained more below). How the Master Vector is created, and the results used, are relevant only in that the format (Master and Boolean, resulting in m x n) must be respected.
For example, if Element 0 has a boolean of False, all m vectors will have the same value for Element 0, V[0]. If Element 1 has a boolean of True, then vector 0 will have Element 1 from V[1], but vector 1 will have Element 1 from V[6]. A Master Vector, V, of;
(1,2,3,4,5,6,10,30,40,60,100,300,400,600)
and a boolean vector of
1, 0, 1, 1, 0, 1
should produce three resulting vectors;
[1 2 3 4 5 6]
[10. 2. 30. 40. 5. 60.]
[100. 2. 300. 400. 5. 600.]
Which share some elements, but not others. I have a methodology for this, but it relies on nested loops and if statements. What I've tried: A working, but inefficient example with 3 resulting vectors of 6 elements:
import numpy as np
p = np.array((1,2,3,4,5,6,10,30,40,60,100,300,400,600))
genome = np.array((1, 0, 1, 1, 0, 1))
index = 0
for i in range(0,3):
if i==0:
pBase = p[0:genome.size]
print(pBase)
else:
extra = np.zeros(genome.size)
for j in range(0,genome.size):
if genome[j]==True:
extra[j] = p[genome.size+index]
index += 1
pSplit = np.where(genome==False, pBase, extra)
print(pSplit)
returns (as expected):
[1 2 3 4 5 6]
[10. 2. 30. 40. 5. 60.]
[100. 2. 300. 400. 5. 600.]
taking 45.1 µs ± 2.4 µs per loop. This seems unnecessarily verbose and slow for what should hypothetically be an easy operation, but I don't know any alternative methods. Is there some combination of list comprehensions or alternative functions that can accomplish the same results in a faster and more pythonic fashion?
EDIT: The values of V will not always be as simple as V10^i, the given vector is just for a demonstration. The values could be considered arbitrary (Generated from another method, following no replicable pattern like 10^i).
Solution
If I understand the question correctly, I the following performs the task in a cleaner manner, but you can let me know what you think.
def convert_vectors(master_vector, boolean_vector):
"""
example:
master_vector = [1,2,3,4,5,6,10,30,40,60,100,300,400,600]
boolean_vector = [1,0,1,1,0,1]
result = [[1, 2, 3, 4, 5, 6],[10, 2, 30, 40, 5, 60],[100, 2, 300, 400, 5, 600]]
"""
res = [] # result
curIndexInMaster = 0 # index in master_vector
while curIndexInMaster < len(master_vector):
curArray = [] # current array
for bool in boolean_vector: # for each element in boolean_vector
if bool: # should get new element from master_vector
curArray.append(master_vector[curIndexInMaster])
curIndexInMaster += 1
else:
curArray.append(master_vector[len(curArray)])
if curIndexInMaster < len(boolean_vector): # only for first array
curIndexInMaster += 1
res.append(curArray)
return res
master_vector = [1, 2, 3, 4, 5, 6, 10, 30, 40, 60, 100, 300, 400, 600]
boolean_vector = [1, 0, 1, 1, 0, 1]
print(convert_vectors(master_vector, boolean_vector))
Output:
[[1, 2, 3, 4, 5, 6], [10, 2, 30, 40, 5, 60], [100, 2, 300, 400, 5, 600]]
Answered By - Plonetheus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.