How to calculate rolling up values in python - python

I have a python dict with the following values
d = {
"k1": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0]],
"k2": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1]],
"k3": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1]],
"k4": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1],[0, 1, 1, 1, 1, 1, 1]]
}
I need to apply a reduce/roll up function on this.
For k1, I am expecting the value as ((1,0,0)+(0,1,1)+(0,0,1)+(0,1,0)+ (0,0,1)+ (1,0,0) -> 1+1+1+1+1+1 =6) and so on), k2 as 4 and for k3, it is 7.
For e.g. for k1, I can calculate using this
k1_sum = sum([x | y | z for x,y,z in zip([0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0])])
k2_sum = sum([x | y for x,y in zip([0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1])])
How do I dynamically unpack the values. There could be several values for each key. It is not fixed. There can be numerous keys.
I would like to write a function and by passing each key, I would like to get the rolled up value.

functools.reduce is perfect for the job:
from operator import or_
from functools import reduce
d = {
"k1": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0]],
"k2": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1]],
"k3": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1]],
"k4": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1]]
}
sums = {key: sum(reduce(or_, t) for t in zip(*xss)) for key, xss in d.items()}
print(sums)
Result:
{'k1': 6, 'k2': 4, 'k3': 7, 'k4': 7}
Don't use heavier libraries than you need to (like numpy), unless you're using them anyway or you find they give you a performance advantage you need.

Related

Numpy array of strings into an array of integers

I have the following array:
pattern = array([['[0, 0, 1, 0, 0]'],
['[0, 1, 1, 1, 1]'],
['[0, 1, 1, 1, 0]'],
['[0, 0, 1, 1, 1]'],
['[0, 0, 0, 1, 1]'],
['[0, 0, 1, 0, 1]'],
['[0, 0, 0, 0, 1]'],
['[1, 0, 1, 0, 0]'],
['[0, 1, 0, 1, 1]'],
['[0, 0, 1, 1, 0]'],
['[1, 1, 1, 1, 1]'],
['[1, 1, 1, 1, 0]']], dtype='<U15')
and I want to get it in non-string format as the following:
import numpy
my_array = numpy.array([[0, 0, 1, 0, 0],
[0, 1, 1, 1, 1],
[0, 1, 1, 1, 0],
[0, 0, 1, 1, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 1],
[1, 0, 1, 0, 0],
[0, 1, 0, 1, 1],
[0, 0, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 0]
])
Any idea on how to do it non-manually?
Using numpy string operations to strip brackets ([]), splitting on comma and recast into an array with int dtype is possible:
np.array(np.char.split(np.char.strip(pattern[:, 0], '[]'), ', ').tolist(), 'int')
but a list comprehension where you do the same things using python string methods is much easier to read (and faster as well) imo.
np.array([row[0][1:-1].split(', ') for row in pattern], dtype='int')
# array([[0, 0, 1, 0, 0],
# [0, 1, 1, 1, 1],
# [0, 1, 1, 1, 0],
# [0, 0, 1, 1, 1],
# [0, 0, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 0, 0, 1],
# [1, 0, 1, 0, 0],
# [0, 1, 0, 1, 1],
# [0, 0, 1, 1, 0],
# [1, 1, 1, 1, 1],
# [1, 1, 1, 1, 0]])

Python 2d array loop

It might be stupid question but I'm starting with python and I have no clue how to write it.
So I want to print this table in loop like on the screen and then I want it to be usable but It's hard for me to write it down (look on screen pls):
table = [print([random.randint(0,1) for x in range(10)]) for y in range(10)]
a = table
print(a)
console output
The values are printed using the print inside the list. But the method print return nothing, None, so you're saving 10 None in the outer list
table = [[random.randint(0, 1) for x in range(10)] for y in range(10)]
for row in table:
print(row)
a = table
print(a)
[1, 0, 0, 1, 1, 0, 1, 1, 1, 1]
[0, 1, 1, 0, 0, 1, 0, 1, 1, 0]
[1, 0, 1, 0, 0, 0, 0, 1, 1, 0]
[1, 1, 1, 1, 0, 1, 1, 1, 0, 0]
[0, 1, 0, 0, 1, 1, 0, 1, 0, 0]
[1, 0, 0, 0, 0, 1, 0, 0, 0, 1]
[0, 1, 0, 1, 1, 1, 0, 0, 0, 0]
[0, 1, 0, 1, 0, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
[1, 1, 0, 0, 0, 0, 1, 1, 0, 0]
[[1, 0, 0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 0, 0, 1, 0, 1, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 1, 0], [1, 1, 1, 1, 0, 1, 1, 1, 0, 0], [0, 1, 0, 0, 1, 1, 0, 1, 0, 0], [1, 0, 0, 0, 0, 1, 0, 0, 0, 1], [0, 1, 0, 1, 1, 1, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 1, 1, 0, 1, 1], [1, 1, 0, 0, 0, 0, 1, 1, 0, 0]]

Numpy, Reading from File with no delimiter, and most efficient way

I'm looking for most efficient way to load file with matrix to numpy array without delimiter.
should I use generator to convert and fill? file consist of single 1 and 0 only
000000000
011111111
111000100
110001110
000001100
001000000
110000000
111111100
to:
[
[0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 0, 0, 0, 1, 0, 0]
...
]
You can use numpy.genfromtxt
import numpy as np
np.genfromtxt('matrix.txt', delimiter=1, dtype=int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 0, 0],
[1, 1, 0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 0, 0]])

Turning a list into list of lists

I am writing a function which takes columns=c and rows=r (both can be unequal!) and that should a list of lists, where each row is a list containing c elements, all rows within a list. How do I create such sublists given the list below?
list = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
should return:
[[0, 0, 0, 0, 0], [1, 1, 0, 1, 1], [0, 0, 1, 1, 1], [1, 1, 1, 1, 0], [0, 1, 0, 1, 1]]
I tried to use split() however it seems like it works for strings only.
Numpy:
import numpy
c, r = 4, 5
list_ = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0]
numpy.array(list_).reshape(c, r).tolist()
#out (shortened example list to avoid 5x5):
[[0, 0, 0, 0, 0], [1, 1, 0, 1, 1], [0, 0, 1, 1, 1], [1, 1, 1, 1, 0]]
However, if your goal is to create "an cxr array with zeroes and ones", you should better use:
numpy.random.randint(0, high=2, size=(c, r))
# out
array([[1, 1, 1, 0, 0],
[1, 1, 0, 0, 0],
[0, 1, 1, 1, 0],
[1, 0, 0, 1, 0]])
Use itertools.islice: (Also don't use list as a variable name. It replaces the builtin function)
from itertools import islice
def chunker(data, rows, cols):
d = iter(data)
return [list(islice(d, cols)) for row in range(rows)]
data = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
result = chunker(data, 4, 5)
Result:
[[0, 0, 0, 0, 0],
[1, 1, 0, 1, 1],
[0, 0, 1, 1, 1],
[1, 1, 1, 1, 0]]
You can use a list comprehension:
c, r = 4, 5
list = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
list_of_lists = [list[i - c: i] for i in range(c, len(list), c)]
l= [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
print([L[i:i+4] for i in range(0,len(L),4)])
output:
[[0, 0, 0, 0], [0, 1, 1, 0], [1, 1, 0, 0], [1, 1, 1, 1], [1, 1, 1, 0], [0, 1, 0, 1], [1]]
using slicing and list comprehension.
new_list=[list[i:i+5] for i in range(len(list)//5)]
just do this like it,it will be done.
a sample usage screenshot
Try this:
ls = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
[ls[i*5:i*5+5] for i in range(len(ls)//5)]
Out[1]:
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 1, 0],
[0, 1, 1, 0, 1]]
Or as a function:
def split_list(list, length):
return [list[i*length:i*length+length] for i in range((len(list)//length))]
split_list(ls, 5)

Add 1 to an element inside a list and return a different list

I wrote the following code:
population = [[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [1], [0]],
[[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]],
[[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]],
[[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [3], [3]]]
def ManipulateFitness(population):
mf=[]
populaion_m = population
for game in range (0, len(population)):
m = [f+1 for f in population[game][1]]
mf.append(m)
manipulted = [m for f in population[game][1] for m in mf
population_m.append(manipulated)
return (population_m)
What I am trying to do is just adding a 1 to the second element in the list (the third is just a counter)for each chromosome and return the same list with just this different values, but with a different name, since Ill need both later on. I was trying it like this but it didnt work, I managed to generate the values but I wasnt successfull in adding them to the list in the correct places. Any suggestions?
This answer assumes that you want to add an additional element 1 to the second item of each list:
population = [[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [1], [0]], [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]], [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]], [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [3], [3]]]
new_population = [[b+[1] if i == 1 else b for i, b in enumerate(a)] for a in population]
Output:
[[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [1, 1], [0]], [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3, 1], [1]], [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4, 1], [2]], [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [3, 1], [3]]]
However, if you merely wish to increment the element in the second list, you can try this:
new_population = [[[b[0]+1] if i == 1 else b for i, b in enumerate(a)] for a in population]
Output:
[[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [2], [0]], [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [4], [1]], [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]], [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [4], [3]]]

Categories

Resources