code: def estimate_size(cls, ctx, op: "DataFrameReadParquet"):
      first_chunk_row_num = op.first_chunk_row_num
      first_chunk_raw_bytes = op.first_chunk_raw_bytes
      raw_bytes = file_size(op.path, storage_options=op.storage_options)
      if op.num_group_rows:
          raw_bytes = (
              np.ceil(np.divide(raw_bytes, op.num_group_rows))
              .astype(np.int64)
              .item()
          )
  
      estimated_row_num = (
          np.ceil(
              first_chunk_row_num * (raw_bytes / first_chunk_raw_bytes)
          )
          .astype(np.int64)
          .item()
      )
      phy_size = raw_bytes * (op.memory_scale or PARQUET_MEMORY_SCALE)
      n_strings = len(
          [dt for dt in op.outputs[0].dtypes if is_object_dtype(dt)]
      )
      pd_size = (
          phy_size
          + n_strings * estimated_row_num * STRING_FIELD_OVERHEAD
      )
      ctx[op.outputs[0].key] = (pd_size, pd_size + phy_size)
  
imports: import os
  from typing import Dict
  from urllib.parse import urlparse
  import numpy
  import pandas
  from ...None import opcodes
  from ...config import options
  from ...lib.filesystem import file_size, get_fs, glob, open_file, FileSystem
  from ...serialization.serializables import AnyField, BoolField, DictField, ListField, StringField, Int32Field, Int64Field
  from ...utils import is_object_dtype, lazy_import
  from ..arrays import ArrowStringDtype
  from ..operands import OutputType
  from ..utils import parse_index, to_arrow_dtypes, contain_arrow_dtype
  from .core import IncrementalIndexDatasource, ColumnPruneSupportedDataSourceMixin, IncrementalIndexDataSourceMixin, merge_small_files
label_desc: Use image node_id 11 for calling the DataFrameReadParquet obj's underlying member method code with example usage: obj.estimate_size(cls, ctx, op) without return types