How to adjust for loop so that it prints list only once?

Viewed 49

I have some sample code that is goes as follows:

import numpy as np
import pandas as pd

x = range(1, 12)
arr1 = np.random.randint(x)
arr2 = np.array(x)
arr3 = np.random.randint(x)
arr4 = np.random.randint(x)
arr5 = np.random.randint(0, 2, 11)

dict_df = {
    'arr1' : arr1,
    'arr2' : arr2,
    'arr3' : arr3,
    'arr4' : arr4,
    'arr5' : arr5
}
d = pd.DataFrame(dict_df)

num_count = 0
list_of_num = []
for i in d.index:
    number = d['arr1'][i]
    for num in d['arr5']:
        if num == 1:
            num_count = 1
            number = number
            list_of_num.append(number)
        elif num == 0:
            num_count = 0
print(list_of_num)

I am trying to build list, into which all of the ones in column arr5 are appended if they are preceeded by a -1. The output I am receiving from this is:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 8, 8, 8, 8, 8, 8]

The issue with the code is that I am misusing for loops, which is why the list has repeated itself so many times. How can I can I change the code so that the code does not repeat itself?

1 Answers

It appears that you did not intend to nest your loops. The outer loop steps over each row. The inner loop then loops over each row for each iteration of the outer loop. To move along two columns in lockstep, you can write a single loop:

for i in d.index:
    if d['arr5'][i]:
        list_of_num.append(d['arr1'][i])
        num_count += 1

This is of course extremely inefficient and discards all the benefits of using numpy or pandas in the first place. You can accomplish the same thing using boolean masks. In numpy:

array_of_num = arr1[arr5.astype(bool)]
num_count = array_of_num.size

In pandas:

series_of_num = d['arr1'][d['arr5'].astype(bool)]
num_count = series_of_num.size

In both cases, you can replace .astype(bool) with != 0.

Related