Append to df using for-loop results in duplicate rows

Solution 1:

You are just checking whether the description is present or not for bio,
you also have to check whether this description belongs to the current user or not.
This should work for bio & same should be applied for image_url.

 # 2. loop for user object
        row['bio']=None # assuming user has no bio
        for user in each_dict['includes']['users']:
            # 5. user bio
            # check for bio of the current user only
            if 'description' in user and user['id']==tweet['author_id']:
                row['bio'] = user.get('description') # if user has bio get bio
                break # break the loop, as user bio is found