Related
Say for example I have these 3 arrays:
# Array 1:
array_1 = [[100, 0, 0, 0, 0, 100],
[0, 100, 0, 0, 0, 100],
[0, 0, 100, 100, 0, 0]]
# Array 2:
array_2 = [[0, 0, 0, 0, 100, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 100]]
# Array 3:
array_3 = [[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 100, 0],
[0, 0, 0, 0, 0, 0]]
How will I be able to combine the 3 arrays into a one single array?
This will be the expected output:
[[100 0 0 0 100 100]
[0 100 0 0 100 100]
[0 0 100 100 0 100]]
As you can see, the 100s from array_1, array_2 and array_3 can be seen in the newly created array.
Combination of 100s must be with the same row as the other.
In this case, you can just add the arrays together
>>> a = np.arange(18).reshape((3,6))
>>> b = np.arange(18).reshape((3,6))
>>> c = np.arange(18).reshape((3,6))
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
>>> a + b + c
array([[ 0, 3, 6, 9, 12, 15],
[18, 21, 24, 27, 30, 33],
[36, 39, 42, 45, 48, 51]])
I have a nested list that contains 1002 time steps and in each time step, I have observation of 11 features. I have read docs related to padding but I really could not find out how to add zero elements at the end of each list. I found out the highest length of lists is for example the 24th item in my main list and now I want to pad all the rest elements based on this unless the 24th element that already in shape.As an example:
a = [[1,2,3,4,5,6,76,7],[2,2,3,4,2,5,5,5,,7,8,9,33,677,8,8,9,9],[2,3,46,7,8,9,],[3,3,3,5],[2,2],[1,1],[2,2]]
a[1] = padding(a[1],len(a[2]) with zeros at the end of the list)
I have done below:
import numpy as np
def pad_or_truncate(some_list, target_len):
return some_list[:target_len] + [0]*(target_len - len(some_list))
for i in range(len(Length)):
pad_or_truncate(Length[i],len(Length[24]))
print(len(Length[i]))
or
for i in range(len(Length)):
df_train_array = np.pad(Length[i],len(Length[24]),mode='constant')
and I got this error: Unable to coerce to Series, length must be 11: given 375
Solution 1
# set the max number of 0
max_len = max([len(x) for x in a])
# add zeros to the lists
temp = [x+ [0]*max_len for x in a]
#Limit the output to the wished length
[x[0:max_len] for x in temp]
Solution 2 using pandas
import pandas as pd
df = pd.DataFrame(a)
df.fillna(0).astype(int).values.tolist()
Output
[[1, 2, 3, 4, 5, 6, 76, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 3, 4, 2, 5, 5, 5, 7, 8, 9, 33, 677, 8, 8, 9, 9],
[2, 3, 46, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[3, 3, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
...]
The following code snippet should pad the individual lists with the appropriate number of 0s(driven by the size of the list with the maximum elements)
def main():
data = [
[1,2,3,4,5,6,76,7],
[2,2,3,4,2,5,5,5,7,8,9,33,677,8,8,9,9],
[2,3,46,7,8,9,],
[3,3,3,5],
[2,2],
[1,1],
[2,2]
]
# find the list with the maximum elements
max_length = max(map(len, data))
for element in data:
for _ in range(len(element), max_length):
element.append(0)
if __name__ == '__main__':
main()
You can use this simple line, which uses np.pad
list(map(lambda x: np.pad(x, (max(map(len, a)) - len(x), 0)).tolist(), a))
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 76, 7],
[2, 2, 3, 4, 2, 5, 5, 5, 7, 8, 9, 33, 677, 8, 8, 9, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 46, 7, 8, 9],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 5],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2]]
Use this if you want to pad at the end instead:
list(map(lambda x: np.pad(x, (0, max(map(len, a)) - len(x))).tolist(), a))
How to use one array filter out another array with non-zero value?
from numpy import array
a = 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]])
b = array([[0, 0, 1, 0, 0],
[0, 0, 2, 0, 0],
[0, 0, 3, 0, 0],
[0, 0, 4, 0, 0],
[0, 0, 5, 0, 0]])
Expected result:
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
Thank you
The easiest way if you want a new array would be np.where with 3 arguments:
>>> import numpy as np
>>> np.where(b, a, 0)
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
If you want to change a in-place you could instead use boolean indexing based on b:
>>> a[b == 0] = 0
>>> a
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 7, 0, 0],
[ 0, 0, 12, 0, 0],
[ 0, 0, 17, 0, 0],
[ 0, 0, 22, 0, 0]])
One line solution:
a * (b != 0)
For every run of x or more consecutive zeros in a list in Python, I would like to del all zeros in the run except for x of them. If x = 0, then delete all zeros.
I was thinking of a Python function that took a list, L, and a number, x, as inputs.
For example, let L = [7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8].
If x = 0, then return L = [7, 12, 2, 27, 10, 8]
If x = 1, then return L = [7, 0, 12, 0, 2, 0, 27, 10, 0, 8]
If x = 2, then return L = [7, 0, 12, 0, 0, 2, 0, 0, 27, 10, 0, 0, 8]
If x = 3, then return L = [7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 8]
If x = 4, then return L = [7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8] (Same as original L)
If x >= 5, then return original L as there are no runs of 5 or more consecutive zeros.
Any help would be sincerely appreciated.
This is easy to do as a generator. Wrap your call to it in a list constructor if you want a fresh list with the zero-runs removed.
def compact_zero_runs(iterable, max_zeros):
zeros = 0
for i in iterable:
if i == 0:
zeros += 1
if zeros <= max_zeros:
yield i
else:
zeros = 0
yield i
Using groupby:
def del_zeros(lst, n):
lst = (list(j)[:n] if i else list(j)
for i,j in itertools.groupby(lst, key=lambda x:x==0))
return [item for sublist in lst for item in sublist]
And the tests:
>>> [del_zeros(L, i) for i in range(5)]
[[7, 12, 2, 27, 10, 8],
[7, 0, 12, 0, 2, 0, 27, 10, 0, 8],
[7, 0, 12, 0, 0, 2, 0, 0, 27, 10, 0, 0, 8],
[7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 8],
[7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8]]
from itertools import groupby, chain, islice
from functools import partial
from operator import eq
def f(L, x):
groups = groupby(L, partial(eq, 0))
return list(chain.from_iterable(islice(v, x) if k else v for k,v in groups))
I have a list of lists and I want to be able to refer to the 1st, 2nd, 3rd, etc. column in a list of lists. Here is my code for the list:
matrix = [
[0, 0, 0, 5, 0, 0, 0, 0, 6],
[8, 0, 0, 0, 4, 7, 5, 0, 3],
[0, 5, 0, 0, 0, 3, 0, 0, 0],
[0, 7, 0, 8, 0, 0, 0, 0, 9],
[0, 0, 0, 0, 1, 0, 0, 0, 0],
[9, 0, 0, 0, 0, 4, 0, 2, 0],
[0, 0, 0, 9, 0, 0, 0, 1, 0],
[7, 0, 8, 3, 2, 0, 0, 0, 5],
[3, 0, 0, 0, 0, 8, 0, 0, 0],
]
I want to be able to say something like:
matrix = [
[0, 0, 0, 5, 0, 0, 0, 0, 6],
[8, 0, 0, 0, 4, 7, 5, 0, 3],
[0, 5, 0, 0, 0, 3, 0, 0, 0],
[0, 7, 0, 8, 0, 0, 0, 0, 9],
[0, 0, 0, 0, 1, 0, 0, 0, 0],
[9, 0, 0, 0, 0, 4, 0, 2, 0],
[0, 0, 0, 9, 0, 0, 0, 1, 0],
[7, 0, 8, 3, 2, 0, 0, 0, 5],
[3, 0, 0, 0, 0, 8, 0, 0, 0],
]
if (The fourth column in this matrix does not have any 1's in it):
(then do something)
I want to know what the python syntax would be for the stuff in parenthesis.
The standard way to perform what you asked is to do a list comprehension
if (The fourth column in this matrix does not have any 1's in it):
translates in:
>>>if not any([1 == row[3] for row in matrix])
However, depending on how often you need to perform this operation, how big is your matrix, etc... you might wish to look into numpy as it is easier (and remarkably faster) to address columns. An example:
>>> import numpy as np
>>> matrix = np.random.randint(0, 10, (5, 5))
>>> matrix
array([[3, 0, 9, 9, 3],
[5, 7, 7, 7, 6],
[5, 4, 6, 2, 2],
[1, 3, 5, 0, 5],
[3, 9, 7, 8, 6]])
>>> matrix[..., 3] #fourth column
array([9, 7, 2, 0, 8])
Try this:
if all(row[3] != 1 for row in matrix):
# do something
The row[3] part takes a look at the fourth element of a row, the for row in matrix part looks at all the rows in the matrix - this produces a list with all the fourth elements in all the rows, that is, the whole fourth column. Now if it is true for all the elements in the fourth column that they're different from one, then the condition is satisfied and you can do what you need inside the if.
A more traditional approach would be:
found_one = False
for i in xrange(len(matrix)):
if matrix[i][3] == 1:
found_one = True
break
if found_one:
# do something
Here I'm iterating over all the rows (i index) of the fourth column (3 index), and checking if an element is equal to one: if matrix[i][3] == 1:. Notice that the for cycle goes from the 0 index up to the "height" of the matrix minus one, that's what the xrange(len(matrix)) part says.
if 1 in [row[3] for row in matrix]: