code: def _bulk_hit(recs, truth, k=None):
      tcounts = truth.reset_index().groupby("LKTruthID")["item"].count()
  
      if k is not None:
          _log.debug("truncating to k for recall")
          tcounts = np.minimum(tcounts, k)
          recs = recs[recs["rank"] <= k]
  
      good = recs.join(truth, on=["LKTruthID", "item"], how="inner")
      gcounts = good.groupby("LKRecID")["item"].count()
  
      # we need all lists, because some might have no truth (oops), some no recs (also oops)
      lists = recs[["LKRecID", "LKTruthID"]].drop_duplicates()
  
      scores = lists.join(
          gcounts.to_frame("ngood"), on="LKRecID", how="left"
      )
      scores["ngood"].fillna(0, inplace=True)
  
      scores = scores.join(
          tcounts.to_frame("nrel"), on="LKTruthID", how="left"
      )
      scores = scores.set_index("LKRecID")
  
      good = scores["ngood"] > 0
      good = good.astype("f4")
      good[scores["nrel"] == 0] = np.nan
      return good
  
file_path: lkpy/lenskit/metrics/topn.py
imports: import logging
  import warnings
  import numpy
  import pandas
label_desc: Use image node_id 7 for calling a global function with example usage: _bulk_hit(recs, truth, k) and returns: good