code: def _concat_chunks_by_worker(chunks, chunk_workers):
      worker_to_chunks = defaultdict(list)
      for chunk, worker in zip(chunks, chunk_workers):
          worker_to_chunks[worker].append(chunk)
      worker_to_concat = dict()
      for worker, chunks in worker_to_chunks.items():
          worker_to_concat[worker] = concat_chunks(chunks)
      return worker_to_concat
  
imports: import itertools
  import logging
  import operator
  import pickle
  from collections import defaultdict
  from functools import reduce
  import numpy
  from ....None import opcodes
  from ....core import ExecutableTuple, OutputType, recursive_tile
  from ....core.context import get_context
  from ....core.operand import MergeDictOperand
  from ....serialization.serializables import FieldTypes, DictField, Int32Field, KeyField, ListField, StringField
  from ...utils import concat_chunks, collect_ports
  from ._align import align_data_set
  from .core import LGBMModelType, get_model_cls_from_type
label_desc: Use image node_id 21 for calling the LGBMTrain obj's underlying member method code with example usage: obj._concat_chunks_by_worker(chunks, chunk_workers) and returns: worker_to_concat