Iterate in ranges in Python - loops

in Python, I need to iterate numbers in ranges like this:
0-200
201-400
401-800
801-1200
etc.
until the len() of a certain file is reached.
i.e. the first steps includes 200 elements and the further ones 199. But it would be no problem, if all of them would include 200, meaning:
0-200
201-401
402-602
603-803
The most important thing is to receive all documents behind these numbers in this ranges of approximately 200 once.
When I tried it, I was not happy with the result:
a = 0
b = 200
for i in range(a, len(files), b):
print(a,b)
print('\n')
a = a+b
b = b+b
because I get this output containing duplicates ("200" is in the first and second range) and missing ranges (e.g. 400-600):
0 200
200 400
600 800
1400 1600
etc.
or this example:
a = 0
b = 200
for i in range(a, len(files), b):
print(a,b)
print('\n')
a = a+b+1
b = b+b
also unsatisfying result:
0 200
201 400
602 800
1403 1600
etc.
There are also some unwanted jumps and for example a missing range between 400 and 600.
Does anyone have an idea how to handle this? As I said, it does not really matter, which exact range is underlying. I just need a constant one covering all numbers once.
Thank you very much!

Ok I seem to have a solution:
a = 0
b = 200
for i in range(a, len(files), b):
print('\n')
print(a, b)
a = a + 200 +1
b = b + 200 +1
delivers the output:
0 200
201 401
402 602
603 803
804 1004
Still thank you, if you've tried anything. I would keep this for possible other people handling the same problem.

Related

In SAS, how to do a loop INSIDE a group using the following characteristics

I have the following problem:
data example;
input channel $ program $ item1 item2 GOAL1 GOAL2;
datalines;
CS A 100 10 100 10
CS A 101 9 100 9
CS B 102 11 102 11
CS B 101 14 101 11
BD A 200 210 200 210
BD A 201 209 200 209
BD B 202 211 202 211
BD B 201 214 201 214
;
run;
First, I need to notice that operations are going to be performed on channel-program level.
Second, a third variable call THIRD equals item1 in its first entry by group. However, in the second entry of third it will vary: if item1_entry1
data poli;
set poli;
by channel program;
array prog{*} A B; /*IN my original data I have 3 programs, so the solution has to be general*/
third=item1; /*So the first entry of item1 will be equal in third*/
do k=1 to dim(prog);
if program=prog{k} then do;
if lag(item1)<lag(item1) then THIRD=lag(item1)
else THIRD=item1;
end;
end;
run;
As expected the code does not give me what I want.
Specifically THIRD and FOURTH should be equal to the variables GOAL1 and GOAL 2.
NOTE: The idea behind the comparison is that always the higher levels are going to be greater or equal than the lower levels, and the lower levels cannot be greater than the upper levels: I can't have 100 and then 101, it should be 100 and 100 for one group.
Your description is a bit unclear. I think you want to compute a new variable want1, which is set to the value of item1 at the beginning of each by group. And within a by group, it decreases if item1 decreases, else stays the same. I would try (untested):
data want;
set example;
by channel program;
retain want1;
if first.program then want1=item1;
else want1=min(want1,item1);
run;

How is an array sliced?

I have some sample code where the array is sliced as follows:
A = X(:,2:300)
What does this mean about the slice of the array?
: stands for 'all' if used by itself and 2:300 gives an array of integers from 2 to 300 with a spacing of 1 (1 is implicit) in MATLAB. 2:300 is the same as 2:1:300 and you can even use any spacing you wish, for example 2:37:300 (result: [2 39 76 113 150 187 224 261 298]) to generate equally spaced numbers.
Your statement says - select every row of the matrix A and columns 2 to 300. Suggested reading

Intertwining 3 arrays in matlab / octave to get correct pattern

I know I can intertwine 2 arrays by
C = [A(:),B(:)].'; %'
D = C(:)
But how can I intertwine 3 arrays with a (pendulum type of pattern going back and forth) See image below with arrows showing the intertwining path pattern I'm trying to get (each column is an array). Also the number pattern I'm trying to get is also next to it, in one large column. Please note the numerical values are just examples to make it easier to read. the numerical values could be decimals also
I tried the code below but the pattern is incorrect.
A=[1,2,3,4,5]
B=[10,20,30,40,50,60,70,80,90]
C=[100,200,300,400,500]
D = [A(:),B(:),C(:)].'; %'
E = D(:)
I get an error in the D array due to the fact that the B array is a larger size than A and C but the number pattern is also not following the pattern I'm trying to get.
1
10
100
2
20
200
3
30
300
4
40
400
5
50
500
error: horizontal dimensions mismatch (5x1 vs 9x1)
The pattern from the 3 arrays I'm trying to get is below.
Please note the numerical values are just examples to make it easier to read. the numerical values could be decimals also
1
10
100
20
2
30
200
40
3
50
300
60
4
70
400
80
5
90
500
PS: I'm using Octave 3.8.1 which is like matlab
Have you tried the following?
D = zeros(4 * size(A, 2) - 1, 1); % initialization
D(1 : 4 : end) = A;
D(2 : 2 : end) = B;
D(3 : 4 : end) = C;

Deleting specific rows within a matrix based on cell values - Matlab

I gave this a search but could only find answers for when the row number is known.
I have a N by 4 matrix and am trying to remove rows based on the specific values in the second column and then the first column.
Initially I approached this the wrong way by filtering the matrix based on the values I didn't want, and then taking it away from the initial matrix, which obviously was not the result I wanted. (see below)
days = [669 680 298 299];
ind = ismember(B(:,2),days);
D = B(ind,:);
C=[B;-D];
I'm assuming there is a very similar way of removing rows, instead of filtering for them?
If you could help me in any way it would be much appreciated!
Edit:
Input:
1002 101 04 92
1002 12 12 298
1002 298 12 589
1002 680 12 589
Output:
1002 101 04 92
1002 12 12 298
I can't use row numbers as the matrix has millions of rows
To remove rows based on second column:
B(ismember(B(:,2),days),:) = [];
or equivalently
B = B(~ismember(B(:,2),days),:);
Or, in your code, change third and fourth lines into
C = B(~ind,:);

Get average of two consecutive values in a vector depending on logical vector

I am reading data from a file and I am trying to do some manipulation on the vector containing the data basically i want to check if the values come from consecutive lines and if so i want to average each two and put the value in a output vector
part of the data and lines
lines=[153 152 153 154 233 233 234 235 280 279 280 281];
Sail=[ 3 4 3 1.5 3 3 1 2 2.5 5 2.5 2 ];
here is what i am doing
Sail=S(lines);
Y=diff(lines)==1;
for ii=1:length(Y)
if Y(ii)
output(ceil(ii/2))=(Sail(ii)+Sail(ii+1))/2;
end
end
is this correct also is there a way to do that without a for loop
Thanks
My suggestion:
y = find(diff(lines)==1);
output = mean([Sail(y);Sail(y+1)]);
This assumes that when you have, say [233 234 235], you want one value averaging the values from lines [233 234] and one value averaging those from [234 245]. If you wanted to do something more complex when longer sets of consecutive lines exist in your data, then the problem becomes more complex.
Incidentally it's a bad idea to do something like (ceil(ii/2)) - you can't guarantee a unique index for each matching value of ii. If you did want an output the same size as Sail (will have zeros in non-matching areas) then you can do something like this:
output2 = zeros(size(Sail));
output2(y)=output;

Resources