Reputation: 97
i thought i understood the global vs local scope for variable but i am struggling on a case.
Here the function i want to implement:
def login_table(id_name_verified, id_password):
"""
:param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified.
:param id_password: (numpy.array) Two-dimensional NumPy array where each element
is an array that contains: Id and Password
:returns: (None) The function should modify id_name_verified DataFrame in-place.
It should not return anything.
Goal : in id_name_verified, 'Verified' column should be removed and password should be added from id_password with corresponding id and the column be named password
"""
Test:
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
id_name_verified.drop(columns="Verified",inplace=True)
password = pd.DataFrame(id_password)
password.columns = ["Id", "Password"]
id_name_verified =id_name_verified.merge(password, on=['Id'])
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
Expected Output:
Id Login Password
0 1 JohnDoe 987340123
1 2 AnnFranklin 187031122
Output i got:
Id Login
0 1 JohnDoe
1 2 AnnFranklin
When I run this on pycharm, i see the problem is in the last line of my function where id_name_verified
is identified as being from outer scope.
This inspection detects shadowing names defined in outer scopes.
If i don't define a function it will work so I guess there is something I miss in the understanding of parameters pass to a function; any suggestions ?
Upvotes: 2
Views: 1984
Reputation: 11
For faster version use mapping. Creating new DataFrame is slow and costly way.
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
"""
:param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified.
:param id_password: (numpy.array) Two-dimensional NumPy array where each element
is an array that contains: Id and Password
:returns: (None) The function should modify id_name_verified DataFrame in-place.
It should not return anything.
"""
id_name_verified.drop(columns='Verified', inplace=True)
mapping = {li[0]: li[1] for li in id_password}
id_name_verified['Password'] = id_name_verified['Id'].map(mapping)
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
Upvotes: 1
Reputation: 318
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
id_name_verified.drop(inplace=True, columns="Verified") # drop verified column inplace
id_name_verified.insert(loc=2,column="Password",value=np.nan) # insert password column inplace
for row in range(len(id_password)):
# apply the password on the rows that match using at
id = id_password[row][0]
pw = id_password[row][1]
id_name_verified.at[row, "Password"] = pw
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
Upvotes: 1
Reputation: 1
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
# in place makes sure that changes are made in a current dataframe
id_name_verified.drop('Verified', 1, inplace= True)
# id_password[:,1] -> : selects all rows and 1 selects only second column
id_name_verified['Password'] = id_password[:,1]
pass
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
Upvotes: 0
Reputation: 31
Here's the code that passes all 4 tests on TestDome:
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
"""
:param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified.
:param id_password: (numpy.array) Two-dimensional NumPy array where each element
is an array that contains: Id and Password
:returns: (None) The function should modify id_name_verified DataFrame in-place.
It should not return anything.
"""
id_name_verified.drop(columns = 'Verified', inplace = True)
password_df = pd.DataFrame(id_password)
pass_col = password_df[1]
id_name_verified['Password'] = pass_col
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
You drop the 'Verified' column, then create a new data frame just out of id_password, take the column that contains passwords and add it to the id_name_verified data frame.
Upvotes: 0
Reputation: 2342
Here is the code that will solve your problem:
import pandas as pd
import numpy as np
def login_table( id_password):
global id_name_verified
id_name_verified.drop(columns="Verified",inplace=True)
password = pd.DataFrame(id_password)
password.columns = ["Id", "Password"]
id_name_verified =id_name_verified.merge(password, on=['Id'])
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table( id_password)
print(id_name_verified)
The changes I made are, I declared the "id_name_verified" as global inside the function "login_table". Once this is done you don't have to pass "id_name_verified" again to the function because by using the keyword "global" we have already given access of "id_name_verified" to the function "login_table". So removed the "id_name_verified" as one of the arguments to the function.
Upvotes: 1