code: def test_negative_feedback_sampler():
      df = pd.DataFrame(
          data={
              "userID": [1, 2, 3],
              "itemID": [1, 2, 3],
              "rating": [5, 5, 5],
          }
      )
  
      # Test ratio < 1
      sample_df = negative_feedback_sampler(
          df,
          col_user="userID",
          col_item="itemID",
          col_label="rating",
          ratio_neg_per_user=0.5,
      )
      assert sample_df.shape == (6, 3)
      assert sample_df.feedback.value_counts().to_dict() == {0: 3, 1: 3}
      for i in [1, 2, 3]:
          assert (
              sample_df[
                  (sample_df.userID == i) & (sample_df.itemID == i)
              ].feedback.values[0]
              == 1
          )
  
      # Test ratio == 1
      sample_df = negative_feedback_sampler(
          df,
          col_user="userID",
          col_item="itemID",
          col_label="rating",
          ratio_neg_per_user=1,
      )
      assert sample_df.shape == (6, 3)
      assert sample_df.feedback.value_counts().to_dict() == {0: 3, 1: 3}
      for i in [1, 2, 3]:
          assert (
              sample_df[
                  (sample_df.userID == i) & (sample_df.itemID == i)
              ].feedback.values[0]
              == 1
          )
  
      res_df = pd.DataFrame(
          data={
              "userID": [1, 2, 3, 1, 1, 2, 2, 3, 3],
              "itemID": [1, 2, 3, 2, 3, 1, 3, 1, 2],
              "feedback": [1, 1, 1, 0, 0, 0, 0, 0, 0],
          }
      )
  
      # Test ratio > 1
      sample_df = negative_feedback_sampler(
          df,
          col_user="userID",
          col_item="itemID",
          col_label="rating",
          ratio_neg_per_user=2,
      )
      assert sample_df.shape == (9, 3)
      assert sample_df.feedback.value_counts().to_dict() == {0: 6, 1: 3}
      assert np.all(
          sample_df.sort_values(["userID", "itemID"]).values
          == res_df.sort_values(["userID", "itemID"]).values
      )
  
      # Test too large ratio
      sample_df = negative_feedback_sampler(
          df,
          col_user="userID",
          col_item="itemID",
          col_label="rating",
          ratio_neg_per_user=3,
      )
      assert sample_df.shape == (9, 3)
      assert sample_df.feedback.value_counts().to_dict() == {0: 6, 1: 3}
      assert np.all(
          sample_df.sort_values(["userID", "itemID"]).values
          == res_df.sort_values(["userID", "itemID"]).values
      )
  
      # Test other options
      sample_df = negative_feedback_sampler(
          df,
          col_user="userID",
          col_item="itemID",
          col_label="rating",
          col_feedback="test_feedback",
          pos_value=2.4,
          neg_value=0.2,
          ratio_neg_per_user=3,
      )
      assert sample_df.columns[2] == "test_feedback"
      assert set(sample_df["test_feedback"].unique()) == set([2.4, 0.2])
  
file_path: recommenders/tests/unit/recommenders/datasets/test_pandas_df_utils.py
imports: import os
  import numpy
  import pandas
  import pytest
  from tempfile import TemporaryDirectory
  from recommenders.datasets.pandas_df_utils import filter_by, LibffmConverter, has_same_base_dtype, has_columns, lru_cache_df, negative_feedback_sampler
label_desc: Use image node_id 2 for calling a global function with example usage: test_negative_feedback_sampler() without return types