Given, two Series bees and knees, if the ith value of bees is NaN, double the ith value inside knees.
import numpy as np
import pandas as pd
bees = pd.Series([True, True, False, np.nan, True, False, True, np.nan])
knees = pd.Series([5,2,9,1,3,10,5,2], index = [7,0,2,6,3,5,1,4])
print(bees)
# 0 True
# 1 True
# 2 False
# {==3 NaN==}
# 4 True
# 5 False
# 6 True
# {==7 NaN==}
# dtype: object
print(knees)
# 7 5
# 0 2
# 2 9
# {==6 1==} <-- double this
# 3 3
# 5 10
# 1 5
# {==4 2==} <-- double this
# dtype: int64
Expected Result
print(knees)
# 7 5
# 0 2
# 2 9
# {==6 2==}
# 3 3
# 5 10
# 1 5
# {==4 4==}
# dtype: int64
Solution¶
knees.loc[pd.isna(bees).to_numpy()] *= 2
print(knees)
# 7 5
# 0 2
# 2 9
# {==6 2==}
# 3 3
# 5 10
# 1 5
# {==4 4==}
# dtype: int64
Explanation
-
Identify which elements of
beesareNaNwithpd.isna().pd.isna(bees) # 0 False # 1 False # 2 False # {==3 True==} # 4 False # 5 False # 6 False # {==7 True==} # dtype: boolThis results in a boolean Series.
-
Suppose we use this boolean Series to index
knees..knees.loc[pd.isna(bees)] # 7 5 # 3 3 # dtype: int64The elements it selects are not the ones we want.
knees.loc[pd.isna(bees)]selects the elements ofkneeswhose index matches those ofpd.isna(bees)with True values.knees.loc[pd.isna(bees)] # pd.isna(bees) knees # 0 False ┌------{==7-----5==} # 1 False | 0 2 # 2 False | 2 9 # {==3-------True==}--┼--┐ 6 1 # 4 False | └---{==3-----3==} # 5 False | 5 10 # 6 False | 1 5 # {==7-------True==}--┘ 4 2In other words,
pd.isna(bees)has True values at indexes 3 and 7, soknees.loc[pd.isna(bees)]selects rows ofkneeswith index 3 and 7.However, the problem asked us to double the ith value of
kneesif the ith value ofbeeswasNaN. The fourth and eighth elements ofbeesareNaN, so we want to select the fourth and eight elements ofknees. (Note thatknees's index is not in sequential order.)To prevent Pandas from using the index of
pd.isna(bees)to select elements ofknees, we can remove the index by converting the boolean Series to a NumPy array. Then Pandas will select elements by the position of True values.knees.loc[pd.isna(bees).to_numpy()] # pd.isna(bees).to_numpy()] knees # False 7 5 # False 0 2 # False 2 9 # {==True==}-------------------------{==6-----1==} # False 3 3 # False 5 10 # False 1 5 # {==True==}-------------------------{==4-----2==} # <result> # 6 1 # 4 2 # dtype: int64 -
Double the value of those elements.
Easy enough, thanks to the
+=operator :fontawesome-regular-face-smile:knees.loc[pd.isna(bees).to_numpy()] *= 2 print(knees) # 7 5 # 0 2 # 2 9 # {==6 2==} # 3 3 # 5 10 # 1 5 # {==4 4==} # dtype: int64