if statement condition not working for last i in the loop

Viewed 76

I wrote for loop to calculate the probability for conditional entropy but if the statement is not working correctly for the last i in the loop.

The array I am trying to iterate through:

joint_age_dia = np.c[data["Ageover50"],data["diabetic"]]
joint_age_dia
array([['True', 'yes'],
       ['False', 'yes'],
       ['False', 'no'],
       ['True', 'yes'],
       ['True', 'no'],
       ['True', 'yes'],
       ['False', 'no'],
       ['False', 'no'],
       ['True', 'yes'],
       ['False', 'no']], dtype=object)

The for loop that I create to get the counts of (Y|X=True), (Y|X=False) is

for i in range(len(joint_age_dia)):
  if joint_age_dia[i][1] == 'yes' and joint_age_dia[i][0] == 'True':
    yy_t += 1

  if joint_age_dia[i][1] == 'yes' and joint_age_dia[i][0] == 'False':
    yy_f += 1

  if joint_age_dia[i][1] == 'no' and joint_age_dia[i][0] == 'True':
    yn_t += 1

  if joint_age_dia[i][1] == 'no' and joint_age_dia[i][0] == 'False':
    yn_f += 1

  else:
    None

print(yy_t) # 4
print(yy_f) # 1
print(yn_t) # 2
print(yn_f) # 3

If the loop works correctly yn_t is supposed to be 1 and yn_f should be 4 but I noticed when i = 10 it counts the last list of the array wrong (Since it's 'no' when the left side element is 'False', yn_f should have been incremented).

I can't figure out what went wrong...

3 Answers

As you have a numpy array, use a vectorial solution:

import pandas as pd
df = pd.DataFrame(joint_age_dia).value_counts()
print(df)

output:

0      1  
False  no     4
True   yes    4
False  yes    1
True   no     1
dtype: int64

Or as dict:

pd.DataFrame(joint_age_dia).value_counts().to_dict()

output:

{('False', 'no'): 4,
 ('True', 'yes'): 4,
 ('False', 'yes'): 1,
 ('True', 'no'): 1}

If really, you need variables:

yy_t, yy_f, yn_t, yn_f = (
 pd.DataFrame(joint_age_dia).value_counts()
   .reindex([('True', 'yes'), ('False', 'yes'), ('True', 'no'), ('False', 'no')])
)

print(yy_t, yy_f, yn_t, yn_f)
# (4, 1, 1, 4)

But this becomes a bit ugly IMO

Honestly, I would just avoid this whole problem entirely. Consider:

>>> from collections import Counter
>>> d = [['True', 'yes'],
...      ['False', 'yes'],
...      ['False', 'no'],
...      ['True', 'yes'],
...      ['True', 'no'],
...      ['True', 'yes'],
...      ['False', 'no'],
...      ['False', 'no'],
...      ['True', 'yes'],
...      ['False', 'no']]
>>> Counter(tuple(i) for i in d) # Have to use tuple because Counter uses a dict 
>>>                              # under the hood and keys have to be hashable.
Counter({('True', 'yes'): 4, ('False', 'no'): 4, ('False', 'yes'): 1, ('True', 'no'): 1})

We're skipping having to make a bunch of conditional checks, so the code is easier to read, and you can trust that it always consumes everything in whatever your collection is because we don't have silly range(len()) stuff happening.

This Works fine, refer to comments from Jan Christoph Terasa, yy_t=0, yy_f=0, yn_t=0, yn_f=0

joint_age_dia = [['True', 'yes'],
                         ['False', 'yes'],
                         ['False', 'no'],
                         ['True', 'yes'],
                         ['True', 'no'],
                         ['True', 'yes'],
                         ['False', 'no'],
                         ['False', 'no'],
                         ['True', 'yes'],
                         ['False', 'no']]
        yy_t=0
        yy_f=0
        yn_t=0
        yn_f=0
        for i in range(len(joint_age_dia)):
            if joint_age_dia[i][1] == 'yes' and joint_age_dia[i][0] == 'True':
                yy_t += 1
    
            if joint_age_dia[i][1] == 'yes' and joint_age_dia[i][0] == 'False':
                yy_f += 1
    
            if joint_age_dia[i][1] == 'no' and joint_age_dia[i][0] == 'True':
                yn_t += 1
    
            if joint_age_dia[i][1] == 'no' and joint_age_dia[i][0] == 'False':
                yn_f += 1
    
            else:
                None
        print(yy_t)  # 4
        print(yy_f)  # 1
        print(yn_t)  # 1
        print(yn_f)  # 4
Related