looking for something in python's standard lib or a syntax trick.
for non-clojure programmers, partition-all should have these semantics:
partition_all(16, lst) == [lst[0:16], lst[16:32], lst[32:48], lst[48:60]]
assuming len(lst) == 60
There is no such function in Python. You can do this:
from itertools import islice
def chunkwise(n, iterable):
it = iter(iterable)
while True:
chunk = list(islice(it, n))
if not chunk:
break
yield chunk
print list(chunkwise(3, range(10)))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
Adding a third "step size" parameter to the range built-in function gets you pretty close:
>>> range(0,60,16)
[0, 16, 32, 48]
You can create tuples for the upper and lower bounds from there:
>>> [(i, i+16) for i in range(0, 60, 16)]
[(0, 16), (16, 32), (32, 48), (48, 64)]
Or create the actual ranges if you need them:
>>> [range(i, i+16) for i in range(0, 60, 16)]
[[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], [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47], [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]]
Naturally you can parameterize the 0, 60, and 16 into your own function if you need to.
I don't think there is a partition_all like function in the standard library so I'm afraid you are writing your own. However looking at https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L5599 I'm thinking you could implement it in Python like this:
>>> from itertools import islice
>>> lst = range(60)
>>> def partition_all(n, lst, step=None, start=0):
... step = step if step is not None else n
... yield islice(lst, start, n)
... while n < len(lst):
... start, n = start + step, n + step
... yield islice(lst, start, n)
...
>>>
>>> for partition in partition_all(16, lst):
... l = list(partition)
... print len(l), l
...
16 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
16 [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
16 [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]
12 [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
>>>
The recipes section of the itertools documentation has a grouper function that does what you want.
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
Beware that there's also a recipe for "partition", but that does something different.
I believe I have a shorter answer which does not require importing any libraries.
Here is a one-liner for you:
>>> lst = list(range(60))
>>> [lst[i * 16: (i + 1) * 16] for i in range(len(lst) / size + int((len(lst) % 16) > 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], [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47], [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]]
Now as a function (assumes that you work with a list):
def partition(lst, size):
assert(size >= 0)
if not lst: return ()
return (lst[i * size: (i + 1) * size] for i in range(len(lst) / size + int((len(lst) % size) > 0)))
>>> partition(list(range(78)), 17)
<generator object <genexpr> at 0x7f284e33d5a0>
>>> list(partition(list(range(78)), 17))
[[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, 32, 33], [34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67], [68, 69, 70, 71, 72, 73, 74, 75, 76, 77]]
>>> list(partition(range(16), 4))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
>>> print list(partition(range(0), 4))
[]
EDIT: New solution based on Triptych's answer:
def partition(lst, size):
assert(size >= 0)
if not lst: return ()
return (lst[i: i + size] for i in range(0, len(lst), size))
>>> partition(list(range(78)), 17)
<generator object <genexpr> at 0x025F5A58>
>>> list(partition(list(range(78)), 17))
[[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, 32, 33], [34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67], [68, 69, 70, 71, 72, 73, 74, 75, 76, 77]]
>>> list(partition(list(range(16)), 17))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
>>> list(partition(list(range(16)), 4))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
>>> list(partition([], 17))
[]
>>>
Related
Each tuple in this list should consist of a train_indices list and a test_indices list containing the training/testing data point indices for that particular K th split.
Below is what we want to achieve with the dataset:
data_indices = [(list_of_train_indices_for_split_1, list_of_test_indices_for_split_1)
(list_of_train_indices_for_split_2, list_of_test_indices_for_split_2)
(list_of_train_indices_for_split_3, list_of_test_indices_for_split_3)
...
...
(list_of_train_indices_for_split_K, list_of_test_indices_for_split_K)]
Here is my current function:
def sklearn_kfold_split(data,K):
kf = KFold(n_splits = K, shuffle = False, random_state = None)
result = next(kf.split(data), None)
return [result]
The output of this function:
sklearn_kfold_split(data,4)
[(array([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57]),
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]))]
I am not sure what i should add or change to get this output below:
[(array([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57]),
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])),
(array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57]),
array([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])),
(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, 28, 29, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57]),
array([30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43])),
(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, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43]),
array([44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]))]
Any help or advice on what I can change on my function
The easiest way to fix this is to use list comprehension to iterate over the results from KFold.split:
import pandas as pd
from sklearn.model_selection import KFold
def sklearn_kfold_split(data, K):
kf = KFold(n_splits=K, shuffle=False, random_state=None)
result = [(train_index, test_index) for train_index, test_index in kf.split(data)]
return result
data = list(range(12))
K = 4
sklearn_kfold_split(data_indices, K)
Output:
[(array([ 3, 4, 5, 6, 7, 8, 9, 10, 11]), array([0, 1, 2])),
(array([ 0, 1, 2, 6, 7, 8, 9, 10, 11]), array([3, 4, 5])),
(array([ 0, 1, 2, 3, 4, 5, 9, 10, 11]), array([6, 7, 8])),
(array([0, 1, 2, 3, 4, 5, 6, 7, 8]), array([ 9, 10, 11]))]
This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 3 years ago.
question
my_list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,...,50]
answer
listOne = [0,1,2,....,9
listTwo = [10,11,12,...,19]
listThree = [20,21,22,...,29]
listFour = [30,31,32,...,39]
listFive = [40,41,42,...,49]
listSix = [50,51,52,...,59]
answer
If we do not know the number to show in my list how to split list
def SplitList(given_list, chunk_size):
return [given_list[offs:offs+chunk_size] for offs in range(0, len(given_list), chunk_size)]
Use this function to pass the list:
chunk_list = SplitList(my_list, 10)
for lst in chunk_list:
print(lst)
You can use mlist[i : i+10] to split every 10 element in a group
#populate list
mlist = []
for i in range (51):
mlist.append(i)
print("##########INPUT##########")
print(mlist)
new = []
for i in range(0, len(mlist), 10):
new.append(mlist[i : i+10])
print("##########OUTPUT##########")
print("Total Group: "+str(len(new)))
for i in range(len(new)):
print(new[i])
The output will be like this
##########INPUT##########
[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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
##########OUTPUT##########
Total Group: 6
[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, 32, 33, 34, 35, 36, 37, 38, 39]
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
[50]
I'm using Python to create a 12*12 multiplication table.
The table is held in memory in a nested list multi_table, where:
multi_table[0][0] holds “X”
The first row holds the number i for every position i
The first column holds the number j for every position j
each product i*j is stored in position multi_table[i][j].
The multiplication table is shown in Figure 1 below.
Figure 1: Multiplication Table
Umm, what is the question? By how to format do you mean how to generate this nested list?
If so, how about:
n = 12
table = [['X'] * (n+1) for _ in range(n+1)]
for i in range(1, n+1):
table[i][0] = i
for j in range(1, n+1):
table[0][j] = j
table[i][j] = i*j
table
[['X', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24],
[3, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36],
[4, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48],
[5, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],
[6, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72],
[7, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84],
[8, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96],
[9, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108],
[10, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
[11, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132],
[12, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144]]
def distancesplit(self):
img = np.asarray(Image.open("testtwo.tif").convert('L'))
img = 1 * (img < 127)
areasplit = np.split(img.ravel(), 24) # here we are splitting converted to 1D array
for i in areasplit:
area = (i == 0).sum()
print area
How to select subarrays in areasplit with minimal, average and maximal area values?
For max:
areasplit[argmax(sum(areasplit==0, axis=0)), :]
replace argmax with argmin for min: have you considered there may be several array meet you criteria?
Example:
>>> from numpy import *
>>> a=array(range(81))
>>> b=split(a, 9)
>>> b#be careful it is a list of arrays not just an array
[array([0, 1, 2, 3, 4, 5, 6, 7, 8]), array([ 9, 10, 11, 12, 13, 14, 15, 16, 17]), \
array([18, 19, 20, 21, 22, 23, 24, 25, 26]), array([27, 28, 29, 30, 31, 32, 33, 34, 35]), \
array([36, 37, 38, 39, 40, 41, 42, 43, 44]), array([45, 46, 47, 48, 49, 50, 51, 52, 53]), \
array([54, 55, 56, 57, 58, 59, 60, 61, 62]), array([63, 64, 65, 66, 67, 68, 69, 70, 71]), \
array([72, 73, 74, 75, 76, 77, 78, 79, 80])]
>>> b=array(split(a, 9)) #I prefer to use b.reshape((-1,9)) over split()., which returns an array.
>>> b#now it is an array
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, 28, 29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42, 43, 44],
[45, 46, 47, 48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59, 60, 61, 62],
[63, 64, 65, 66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77, 78, 79, 80]])
>>> b[argmax(sum(b, axis=1)), :]
array([72, 73, 74, 75, 76, 77, 78, 79, 80])
>>> b[argmin(sum(b, axis=1)), :]
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> b[argwhere(median(b)==median(b, axis=1)).flatten(),:] #be careful there may be several matching sub-arrays
array([[36, 37, 38, 39, 40, 41, 42, 43, 44]])
>>> b[argwhere(mean(b)==mean(b, axis=1)).flatten(),:]
array([[36, 37, 38, 39, 40, 41, 42, 43, 44]])
import random
orig=list(range(1,65))
temp_orig= [[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],
[32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55],
[56, 57, 58, 59, 60, 61, 62, 63]]
ip= [[40, 24, 9, 41, 42, 56, 43, 45],
[4, 23, 21, 60, 35, 6, 59, 0],
[36, 53, 32, 16, 7, 37, 17, 18],
[10, 62, 61, 38, 29, 34, 31, 25],
[54, 57, 51, 49, 39, 3, 50, 30],
[11, 46, 33, 27, 44, 15, 13, 48],
[12, 58, 1, 26, 47, 20, 28, 52],
[19, 55, 2, 63, 22, 8, 14, 5]]
ipinv=[[15, 50, 58, 37, 8, 63, 13, 20],
[61, 2, 24, 40, 48, 46, 62, 45],
[19, 22, 23, 56, 53, 10, 60, 9],
[1, 31, 51, 43, 54, 28, 39, 30],
[18, 42, 29, 12, 16, 21, 27, 36],
[0, 3, 4, 6, 44, 7, 41, 52],
[47, 35, 38, 34, 55, 17, 32, 57],
[5, 33, 49, 14, 11, 26, 25, 59]]
print "\n\nOriginal position of Bits:"
for i in range(len(ipinv)):
print "\t",temp_orig[i]
print "\n\nInitial Permutation Table"
for i in range(len(ipinv)):
print "\t",ip[i]
print "\n\nInverse Initail permutation Table"
for i in range(len(ipinv)):
print "\t",ipinv[i]
print "\nRound 1:Initial Permutation"
plaintext=list(raw_input("\n\tEnter not more than 8 char:"))
l=len(plaintext)
for i in range(8,len(plaintext)):
del plaintext[l-1+8-i]
print "\n\tPlain text:",plaintext,"\n"
for i in range(8):
plaintext[i]=list(bin(ord(plaintext[i])).zfill(8))
print "\t",plaintext[i]
ip1=temp_orig
for i in range(8):
for j in range(8):
ip1[i][j]=plaintext[(ip[i][j])/8][(ip[i][j])%8]
print "\nEnciphered list:"
for i in range(8):
print "\t",ip1[i]
print "\n73\n",ip1[7][3],"\n73"
ip1_d=temp_orig
for i in range(8):
for j in range(8):
ip1_d[i][j]=ip1[(ipinv[i][j])/8][(ipinv[i][j])%8]
print ip1[7][3],"ip1_d",[i],[j],"=ip1[",(ipinv[i][j])/8,"][",(ipinv[i][j])%8,"]"
#print "ip1_d",[i],[j],"=",ip1[(ipinv[i][j])/8][(ipinv[i][j])%8]
print "\nDeciphered list:"
for i in range(8):
print "\t",ip1_d[i]
The de sunstitution becomes wrong, just for example i tried printing ip1[7][3] and all of a sudden it changes value when i=7 and j=3 without any assignment to ip1
You do ip1=temp_orig a few times. That tells me that you probably think this copies the temp_orig list - it does not. You have to explicitly copy the list here:
ip1=[list(row) for row in temp_orig]
and so on. Your code just gives new names to temp_orig but still modifies the temp_orig list.
I think this is the most chaotic code I've seen in a while. You should start thinking more in terms of transformations of your data instead of juggling indices like this. I still have no idea what your code does or how it's supposed to work.