@time_function
def filter_used_features(customers_data, feat, digital_features):
    """
    Filters out already used features from recommendations.
    
    Args:
    customers_data (DataFrame): Customer data with initial recommendations.
    feat (DataFrame): Feature usage data.
    digital_features (list): List of digital features to consider.
    
    Returns:
    DataFrame: Updated customer data with filtered recommendations.
    """
    print("Filtering out already used features from recommendations...")
    
    # Ensure all digital features are in feat columns
    feat_digital_features = [col for col in digital_features if col in feat.columns]
    
    # Create a dictionary to store used features for each client_id and product description
    used_features_dict = {}
    for _, row in feat.iterrows():
        try:
            key = (row['client_id'], row['description_of_product_name'])
            if isinstance(key[0], pd.Series) or isinstance(key[1], pd.Series):
                key = (tuple(key[0]) if isinstance(key[0], pd.Series) else key[0],
                       tuple(key[1]) if isinstance(key[1], pd.Series) else key[1])
            used = set(col for col in feat_digital_features if row[col] == 1)
            used_features_dict[key] = used
        except Exception as e:
            print(f"Error processing row: {row}")
            print(f"Error message: {str(e)}")
    
    def filter_recommendations(row):
        try:
            key = (row['client_id'], row['description_of_product_name'])
            if isinstance(key[0], pd.Series) or isinstance(key[1], pd.Series):
                key = (tuple(key[0]) if isinstance(key[0], pd.Series) else key[0],
                       tuple(key[1]) if isinstance(key[1], pd.Series) else key[1])
            used = used_features_dict.get(key, set())
            recommended = row['recommended_features']
            if isinstance(recommended, str):
                recommended = eval(recommended)  # Convert string representation of list to actual list
            filtered = [rec for rec in recommended if rec not in used]
            return filtered + [''] * (10 - len(filtered)) if len(filtered) < 10 else filtered[:10]
        except Exception as e:
            print(f"Error processing recommendation for client_id: {row['client_id']}")
            print(f"Error message: {str(e)}")
            return row['recommended_features']  # Return original recommendations if there's an error
    
    # Apply the filtering
    customers_data['filtered_recommendations'] = customers_data.apply(filter_recommendations, axis=1)
    
    print("Completed filtering out used features from recommendations.")
    
    # Diagnostic prints
    print("\nSample of filtered recommendations:")
    print(customers_data[['client_id', 'description_of_product_name', 'recommended_features', 'filtered_recommendations']].head())
    print("\nDistribution of filtered recommendation lengths:")
    print(customers_data['filtered_recommendations'].apply(lambda x: len([i for i in x if i != ''])).value_counts().sort_index())
    
    return customers_data

# Usage
customers_data = filter_used_features(customers_data, feat, digital_features)

# Additional diagnostic prints
print("\nShape of customers_data:", customers_data.shape)
print("\nColumns in customers_data:", customers_data.columns.tolist())
print("\nShape of feat:", feat.shape)
print("\nColumns in feat:", feat.columns.tolist())
print("\nSample row from feat:")
print(feat.iloc[0])
this logic seems bit complex can you simipliy this easily