Loop to factor given list - python

I have data l:
[[Timestamp('2022-07-14 00:01:00'), Timestamp('2022-07-14 00:11:00'), 1],
[Timestamp('2022-07-14 00:08:00'), Timestamp('2022-07-14 00:18:00'), 1],
[Timestamp('2022-07-14 00:15:00'), Timestamp('2022-07-14 00:25:00'), 1],
[Timestamp('2022-07-14 00:22:00'), Timestamp('2022-07-14 00:32:00'), 0],
[Timestamp('2022-07-14 00:29:00'), Timestamp('2022-07-14 00:39:00'), 0],
[Timestamp('2022-07-14 00:36:00'), Timestamp('2022-07-14 00:46:00'), 1],
[Timestamp('2022-07-14 00:43:00'), Timestamp('2022-07-14 00:53:00'), 1],
[Timestamp('2022-07-14 00:50:00'), Timestamp('2022-07-14 01:00:00'), 1],
[Timestamp('2022-07-14 00:57:00'), Timestamp('2022-07-14 01:07:00'), 0],
[Timestamp('2022-07-14 01:04:00'), Timestamp('2022-07-14 01:14:00'), 1],
[Timestamp('2022-07-14 01:11:00'), Timestamp('2022-07-14 01:21:00'), 1],
[Timestamp('2022-07-14 01:18:00'), Timestamp('2022-07-14 01:28:00'), 1],
[Timestamp('2022-07-14 01:25:00'), Timestamp('2022-07-14 01:35:00'), 0],
[Timestamp('2022-07-14 01:32:00'), Timestamp('2022-07-14 01:42:00'), 0]]
I need a loop to factor this data to obtain first timestamp where l[i][2] == 1 and second timestamp where l[i][2] is 1 consecutively in a row.
expected output:
Timestamp('2022-07-14 00:01:00'), Timestamp('2022-07-14 00:25:00')
...

Try this.
start = None
end = None
for i in range(len(l)):
if l[i][2] == 1:
if start is None:
start = l[i][0]
end = l[i][1]
elif start is not None:
break
print(start, end)

Should work smoothly:
results = []
start = None
for i in range(len(l)):
if l[i][2] == 1:
if start is None:
start = l[i][0]
else:
end = l[i][1]
results.append((start, end))
start = None
print(results)

Related

Performing operation on 2D array using indices from 1D array

I have the following array in python:
a = np.array([[1,1,1],[1,1,1],[1,1,1]])
and the following index array:
b = np.array([0,1,2])
I want to index a using b such that I can subtract 1 from the matching row/column and get the following result:
[[0,1,1],[1,0,1],[1,1,0]]
I can do it using loops, wanted to know if there was a "non-loop" way of doing it.
for i in range(len(b)):
a[i][b[i]] = a[i][b[i]] - 1
It looks like there is some confusion on how to handle this.
You want a simple indexing:
a[np.arange(len(a)), b] -= 1
Output:
array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]])
Output for b = np.array([2,0,1])
array([[1, 1, 0],
[0, 1, 1],
[1, 0, 1]])
Your code produces output as follows:
a = np.array([[1,1,1],[1,1,1],[1,1,1]])
b = np.array([0,1,2])
for i in range(len(b)):
a[i][b[i]] = a[i][b[i]] - 1
Output:
array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]])
This can be done in non -loopy way as follows:
a[np.arange(len(b)),b] -= 1
print(a)
Output:
array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]])

nested list content does not preserve when appending to a main list

I'm working on a basic program allows me to navigate in a two dimensions grid (for now 3X3), using a function specified with the initial point and all the steps moved on each axis, returning the end point. I want to raise an error if a specific point has been already visited, and I'm trying to do it by logging all previous points. This is my code:
matrix = [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
def position(inital_point,*steps):
end_point = inital_point
point_logs = []
point_logs += end_point
for step in steps:
end_point[0] += step[0]; end_point[1] += step[1]
point_logs += end_point
print(point_logs)
My problem is, I want to reference each point with a nested list inside the main list, but the code above is giving me this result:
position([1,1],[1,1],[1,1])
>>>[1, 1, 2, 2, 3, 3]
When I try to convert it to a nested list, I get:
matrix = [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
def position(inital_point,*steps):
end_point = inital_point
point_logs = []
point_logs += [end_point]
for step in steps:
end_point[0] += step[0]; end_point[1] += step[1]
point_logs += [end_point]
print(point_logs)
position([1,1],[1,1],[1,1])
>>> [[3, 3], [3, 3], [3, 3]]
Instead of simply [[1, 1],[2, 2],[3, 3]], please help!
This approach basically takes the last appended points from point_logs and adds the new coordinates to it after which it is also appended.
def position(inital_point,*steps):
end_point = inital_point
point_logs = []
point_logs.append(end_point)
for step in steps:
x, y = point_logs[-1]
point_logs.append([x+step[0], y+step[1]])
print(point_logs)
Output
[[1, 1], [2, 2], [3, 3]]

How to find all the permutations of a variable amount of 0's and 1's recursively (without using itertools or random)?

I'm trying to produce all permutations of a certain number of numbers (for example, 0s and 1s) for a variable number of positions. I will call the number of numbers ord (e.g. ord=2 for only 0s and 1s; ord=3 for 0s, 1s, and 2s) and the number of positions Num. Hence the number of permutations is ord**Num.
Note: I don't want to use itertools or any other types of built-in functions. I'm asking this out of curiosity, not just trying to find a solution.
For ord=2 and Num=3, the output, in any order, should be:
[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
This can be accomplished by:
ord = 2
mylist = []
for a in range(ord):
for b in range(ord):
for c in range(ord):
mylist.append([a,b,c])
For ord = 2 and Num = 4, the output should be:
[[0,0,0,0],[0,0,0,1],[0,0,1,0],[0,0,1,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1],[1,0,0,0],[1,0,0,1],[1,0,1,0],[1,0,1,1],[1,1,0,0],[1,1,0,1],[1,1,1,0],[1,1,1,1]]
But then I would have to add another nested for loop:
ord = 2
mylist = []
for a in range(ord):
for b in range(ord):
for c in range(ord):
for d in range(ord):
mylist.append([a,b,c,d])
An obvious solution is to add 0s and 1s randomly to a list of length Num and then to accept that list if it hasn't already been added to mylist, but I want a solution that isn't quite so ridiculous.
This is the closest I've gotten so far to a real solution:
def myperms(elem, mylist):
for i in range(len(elem)-1,-1,-1):
while (elem[i] + 1) < ord:
elem = list(elem)
elem[i] += 1
if elem not in mylist:
mylist.append(elem)
if (elem[i] + 1) >= ord:
elem = list(elem)
elem[i] = 0
return mylist
Num = 3
ord = 2
TotsNum = ord**Num
mylist = []
elem = [0,]*Num
mylist.append(elem)
print(myperms(elem, mylist))
But this only gives:
[[0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0]]
I've tried calling the function within itself (recursion), but I haven't been able to figure out how to do it properly. Does anyone have any ideas about how to solve it recursively? Thank you!
Let's use a recursive solution:
def get_seq(ord, num):
val = [0]*num
N = num
def recurse(ord, num):
for i in range(ord):
val[N - num] = i
if num > 1:
yield from recurse(ord, num-1)
else:
yield val[:]
return recurse(ord, num)
print(list(get_seq(2, 4)))
Output:
[[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 1, 0, 0],
[0, 1, 0, 1],
[0, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 0],
[1, 1, 0, 1],
[1, 1, 1, 0],
[1, 1, 1, 1]]
For other inputs:
>>> list(get_seq(3, 2))
[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
Use binary, which consists of 0s and 1s.
n = 4
all_permutations = []
for i in range(2**n):
permutation = []
string = bin(i)
string = string.split("0b")[1]
while len(string) != n:
string = f"0{string}"
for i in string:
permutation.append(int(i))
all_permutations.append(permutation)
print(all_permutations)

Sum up indentical list elements

I have an array with elements, and I want to sum up the accuracy. I want to sum the arrays that have the elements in the same order. I rather not be writing a for loop going through each element with zip and summing them up, is there an easier way to do this?
The two arrays are as follows, and currently my code is below for calculating the sum.
yp = [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
y = [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
sums = np.sum(yp == y)
I am getting an accuracy of zero.
Using your example:
yp = [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
y = [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
# First make the two arrays in question numpy arrays.
yp = np.array(yp)
y = np.array(y)
array_length = y.shape[1] # store length of sub arrays
equal_elements = np.array(yp) == np.array(y) # check all equal elements
sums = np.sum(equal_elements, 1) # sum the number of equal elements in each sub array, use axis 1 as each array/sample is axis 0
equal_arrays = np.where(sums==array_length)[0] # returns a tuple, so index first element immediately
number_equal_arrays = equal_arrays.shape[0] # What elements are equal
print('Number of equal arrays %d' % number_equal_arrays)
print('Accuracy %0.2f' % (number_equal_arrays/yp.shape[0]))
prints
Number of equal arrays 6
Accuracy 1.00

Print recursion steps

I would like to print the steps my program made and put these steps in a list. But i can't figure out why my code prints the wrong output. I am new to programming and i hope somoene could help. This is my code:
r=[]
listOfsteps = []
j = 0
class Main(object):
def __init__(self):
i=0
while i != 1:
self.method(r, j)
i+=1
def method(self, r, j):
r.append(j)
listOfsteps.append(r)
j+=1
if j ==5:
return "stop"
print r
print "ListOfSteps", listOfsteps
return self.method(r, j)
Main()
Output now:
[0]
ListOfSteps [[0]]
[0, 1]
ListOfSteps [[0, 1], [0, 1]]
[0, 1, 2]
ListOfSteps [[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[0, 1, 2, 3]
ListOfSteps [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
Output that I want:
[0]
ListOfSteps [[0]]
[0, 1]
ListOfSteps [[0], [0, 1]]
[0, 1, 2]
ListOfSteps [[0], [0, 1], [0, 1, 2]]
[0, 1, 2, 3]
ListOfSteps [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]]
Use:
listOfsteps.append(list(r))
Instead of:
listOfsteps.append(r)
in your version you append a reference to r and in the next iteration you change r so the reference you have stored is affected. You need to copy a list you want to append.
You could also use copy for doing this.
r=[]
listOfsteps = []
j = 0
class Main(object):
def __init__(self):
#you don't need loop while for your example
self.method(r, j)
def method(self, r, j):
r.append(j)
# append only the steps index
#you don't need to add whole list for every step
listOfsteps.append(j)
j+=1
if j == 5:
return "stop"
print r
#to print your step with your output that you want use this loop
l = [listOfsteps[:i+1] for i in range(len(listOfsteps))]
print "ListOfSteps", l
return self.method(r, j)
Main()

Categories

Resources