예제 #1
0
    def get_indexer(self, target, method=None, limit=None, tolerance=None):
        if com.any_not_none(method, tolerance,
                            limit) or not is_list_like(target):
            return super().get_indexer(target,
                                       method=method,
                                       tolerance=tolerance,
                                       limit=limit)

        if self.step > 0:
            start, stop, step = self.start, self.stop, self.step
        else:
            # GH 28678: work on reversed range for simplicity
            reverse = self._range[::-1]
            start, stop, step = reverse.start, reverse.stop, reverse.step

        target_array = np.asarray(target)
        if not (is_integer_dtype(target_array) and target_array.ndim == 1):
            # checks/conversions/roundings are delegated to general method
            return super().get_indexer(target,
                                       method=method,
                                       tolerance=tolerance)

        locs = target_array - start
        valid = (locs % step == 0) & (locs >= 0) & (target_array < stop)
        locs[~valid] = -1
        locs[valid] = locs[valid] / step

        if step != self.step:
            # We reversed this range: transform to original locs
            locs[valid] = len(self) - 1 - locs[valid]
        return ensure_platform_int(locs)
예제 #2
0
파일: range.py 프로젝트: wesbarnett/pandas
    def _get_indexer(
        self,
        target: Index,
        method: str | None = None,
        limit: int | None = None,
        tolerance=None,
    ) -> npt.NDArray[np.intp]:
        if com.any_not_none(method, tolerance, limit):
            return super()._get_indexer(
                target, method=method, tolerance=tolerance, limit=limit
            )

        if self.step > 0:
            start, stop, step = self.start, self.stop, self.step
        else:
            # GH 28678: work on reversed range for simplicity
            reverse = self._range[::-1]
            start, stop, step = reverse.start, reverse.stop, reverse.step

        target_array = np.asarray(target)
        locs = target_array - start
        valid = (locs % step == 0) & (locs >= 0) & (target_array < stop)
        locs[~valid] = -1
        locs[valid] = locs[valid] / step

        if step != self.step:
            # We reversed this range: transform to original locs
            locs[valid] = len(self) - 1 - locs[valid]
        return ensure_platform_int(locs)
예제 #3
0
파일: api.py 프로젝트: yashukla/pandas
def get_consensus_names(indexes):
    """
    Give a consensus 'names' to indexes.

    If there's exactly one non-empty 'names', return this,
    otherwise, return empty.

    Parameters
    ----------
    indexes : list of Index objects

    Returns
    -------
    list
        A list representing the consensus 'names' found.
    """

    # find the non-none names, need to tupleify to make
    # the set hashable, then reverse on return
    consensus_names = {
        tuple(i.names)
        for i in indexes if com.any_not_none(*i.names)
    }
    if len(consensus_names) == 1:
        return list(list(consensus_names)[0])
    return [None] * indexes[0].nlevels
예제 #4
0
    def _get_indexer(
        self,
        target: Index,
        method: str | None = None,
        limit: int | None = None,
        tolerance=None,
    ) -> np.ndarray:
        # -> np.ndarray[np.intp]
        if com.any_not_none(method, tolerance, limit):
            return super()._get_indexer(
                target, method=method, tolerance=tolerance, limit=limit
            )

        if self.step > 0:
            start, stop, step = self.start, self.stop, self.step
        else:
            # GH 28678: work on reversed range for simplicity
            reverse = self._range[::-1]
            start, stop, step = reverse.start, reverse.stop, reverse.step

        if not is_signed_integer_dtype(target):
            # checks/conversions/roundings are delegated to general method
            return super()._get_indexer(target, method=method, tolerance=tolerance)

        target_array = np.asarray(target)
        locs = target_array - start
        valid = (locs % step == 0) & (locs >= 0) & (target_array < stop)
        locs[~valid] = -1
        locs[valid] = locs[valid] / step

        if step != self.step:
            # We reversed this range: transform to original locs
            locs[valid] = len(self) - 1 - locs[valid]
        return ensure_platform_int(locs)
예제 #5
0
파일: core.py 프로젝트: ygene2/pandas
    def _get_index_name(self):
        if isinstance(self.data.index, ABCMultiIndex):
            name = self.data.index.names
            if com.any_not_none(*name):
                name = ",".join(pprint_thing(x) for x in name)
            else:
                name = None
        else:
            name = self.data.index.name
            if name is not None:
                name = pprint_thing(name)

        return name
예제 #6
0
파일: core.py 프로젝트: ygene2/pandas
    def _make_plot(self):
        if self._is_ts_plot():
            from pandas.plotting._matplotlib.timeseries import _maybe_convert_index

            data = _maybe_convert_index(self._get_ax(0), self.data)

            x = data.index  # dummy, not used
            plotf = self._ts_plot
            it = self._iter_data(data=data, keep_index=True)
        else:
            x = self._get_xticks(convert_period=True)
            plotf = self._plot
            it = self._iter_data()

        stacking_id = self._get_stacking_id()
        is_errorbar = com.any_not_none(*self.errors.values())

        colors = self._get_colors()
        for i, (label, y) in enumerate(it):
            ax = self._get_ax(i)
            kwds = self.kwds.copy()
            style, kwds = self._apply_style_colors(colors, kwds, i, label)

            errors = self._get_errorbars(label=label, index=i)
            kwds = dict(kwds, **errors)

            label = pprint_thing(label)  # .encode('utf-8')
            kwds["label"] = label

            newlines = plotf(
                ax,
                x,
                y,
                style=style,
                column_num=i,
                stacking_id=stacking_id,
                is_errorbar=is_errorbar,
                **kwds,
            )
            self._add_legend_handle(newlines[0], label, index=i)

            if self._is_ts_plot():

                # reset of xlim should be used for ts data
                # TODO: GH28021, should find a way to change view limit on xaxis
                lines = _get_all_lines(ax)
                left, right = _get_xlim(lines)
                ax.set_xlim(left, right)
예제 #7
0
    def _make_plot(self):
        if self._is_ts_plot():
            from pandas.plotting._matplotlib.timeseries import _maybe_convert_index

            data = _maybe_convert_index(self._get_ax(0), self.data)

            x = data.index  # dummy, not used
            plotf = self._ts_plot
            it = self._iter_data(data=data, keep_index=True)
        else:
            x = self._get_xticks(convert_period=True)
            plotf = self._plot
            it = self._iter_data()

        stacking_id = self._get_stacking_id()
        is_errorbar = com.any_not_none(*self.errors.values())

        colors = self._get_colors()
        for i, (label, y) in enumerate(it):
            ax = self._get_ax(i)
            kwds = self.kwds.copy()
            style, kwds = self._apply_style_colors(colors, kwds, i, label)

            errors = self._get_errorbars(label=label, index=i)
            kwds = dict(kwds, **errors)

            label = pprint_thing(label)  # .encode('utf-8')
            kwds["label"] = label

            newlines = plotf(
                ax,
                x,
                y,
                style=style,
                column_num=i,
                stacking_id=stacking_id,
                is_errorbar=is_errorbar,
                **kwds
            )
            self._add_legend_handle(newlines[0], label, index=i)

            # GH27686 set_xlim will truncate xaxis to fixed space
            ax.relim()
예제 #8
0
    def _format_hierarchical_rows(self) -> Iterable[ExcelCell]:
        if self._has_aliases or self.header:
            self.rowcounter += 1

        gcolidx = 0

        if self.index:
            index_labels = self.df.index.names
            # check for aliases
            if self.index_label and isinstance(
                    self.index_label, (list, tuple, np.ndarray, Index)):
                index_labels = self.index_label

            # MultiIndex columns require an extra row
            # with index names (blank if None) for
            # unambiguous round-trip, unless not merging,
            # in which case the names all go on one row Issue #11328
            if isinstance(self.columns, MultiIndex) and self.merge_cells:
                self.rowcounter += 1

            # if index labels are not empty go ahead and dump
            if com.any_not_none(*index_labels) and self.header is not False:

                for cidx, name in enumerate(index_labels):
                    yield ExcelCell(self.rowcounter - 1, cidx, name,
                                    self.header_style)

            if self.merge_cells:
                # Format hierarchical rows as merged cells.
                level_strs = self.df.index.format(sparsify=True,
                                                  adjoin=False,
                                                  names=False)
                level_lengths = get_level_lengths(level_strs)

                for spans, levels, level_codes in zip(level_lengths,
                                                      self.df.index.levels,
                                                      self.df.index.codes):

                    values = levels.take(
                        level_codes,
                        allow_fill=levels._can_hold_na,
                        fill_value=levels._na_value,
                    )

                    for i, span_val in spans.items():
                        spans_multiple_cells = span_val > 1
                        yield ExcelCell(
                            row=self.rowcounter + i,
                            col=gcolidx,
                            val=values[i],
                            style=self.header_style,
                            mergestart=(self.rowcounter + i + span_val -
                                        1 if spans_multiple_cells else None),
                            mergeend=gcolidx if spans_multiple_cells else None,
                        )
                    gcolidx += 1

            else:
                # Format hierarchical rows with non-merged values.
                for indexcolvals in zip(*self.df.index):
                    for idx, indexcolval in enumerate(indexcolvals):
                        yield ExcelCell(
                            row=self.rowcounter + idx,
                            col=gcolidx,
                            val=indexcolval,
                            style=self.header_style,
                        )
                    gcolidx += 1

        yield from self._generate_body(gcolidx)
예제 #9
0
    def _translate(self):
        """
        Convert the DataFrame in `self.data` and the attrs from `_build_styles`
        into a dictionary of {head, body, uuid, cellstyle}.
        """
        table_styles = self.table_styles or []
        caption = self.caption
        ctx = self.ctx
        precision = self.precision
        hidden_index = self.hidden_index
        hidden_columns = self.hidden_columns
        uuid = self.uuid or str(uuid1()).replace("-", "_")
        ROW_HEADING_CLASS = "row_heading"
        COL_HEADING_CLASS = "col_heading"
        INDEX_NAME_CLASS = "index_name"

        DATA_CLASS = "data"
        BLANK_CLASS = "blank"
        BLANK_VALUE = ""

        def format_attr(pair):
            return "{key}={value}".format(**pair)

        # for sparsifying a MultiIndex
        idx_lengths = _get_level_lengths(self.index)
        col_lengths = _get_level_lengths(self.columns, hidden_columns)

        cell_context = dict()

        n_rlvls = self.data.index.nlevels
        n_clvls = self.data.columns.nlevels
        rlabels = self.data.index.tolist()
        clabels = self.data.columns.tolist()

        if n_rlvls == 1:
            rlabels = [[x] for x in rlabels]
        if n_clvls == 1:
            clabels = [[x] for x in clabels]
        clabels = list(zip(*clabels))

        cellstyle = []
        head = []

        for r in range(n_clvls):
            # Blank for Index columns...
            row_es = [
                {
                    "type": "th",
                    "value": BLANK_VALUE,
                    "display_value": BLANK_VALUE,
                    "is_visible": not hidden_index,
                    "class": " ".join([BLANK_CLASS]),
                }
            ] * (n_rlvls - 1)

            # ... except maybe the last for columns.names
            name = self.data.columns.names[r]
            cs = [
                BLANK_CLASS if name is None else INDEX_NAME_CLASS,
                "level{lvl}".format(lvl=r),
            ]
            name = BLANK_VALUE if name is None else name
            row_es.append(
                {
                    "type": "th",
                    "value": name,
                    "display_value": name,
                    "class": " ".join(cs),
                    "is_visible": not hidden_index,
                }
            )

            if clabels:
                for c, value in enumerate(clabels[r]):
                    cs = [
                        COL_HEADING_CLASS,
                        "level{lvl}".format(lvl=r),
                        "col{col}".format(col=c),
                    ]
                    cs.extend(
                        cell_context.get("col_headings", {}).get(r, {}).get(c, [])
                    )
                    es = {
                        "type": "th",
                        "value": value,
                        "display_value": value,
                        "class": " ".join(cs),
                        "is_visible": _is_visible(c, r, col_lengths),
                    }
                    colspan = col_lengths.get((r, c), 0)
                    if colspan > 1:
                        es["attributes"] = [
                            format_attr({"key": "colspan", "value": colspan})
                        ]
                    row_es.append(es)
                head.append(row_es)

        if (
            self.data.index.names
            and com.any_not_none(*self.data.index.names)
            and not hidden_index
        ):
            index_header_row = []

            for c, name in enumerate(self.data.index.names):
                cs = [INDEX_NAME_CLASS, "level{lvl}".format(lvl=c)]
                name = "" if name is None else name
                index_header_row.append(
                    {"type": "th", "value": name, "class": " ".join(cs)}
                )

            index_header_row.extend(
                [{"type": "th", "value": BLANK_VALUE, "class": " ".join([BLANK_CLASS])}]
                * (len(clabels[0]) - len(hidden_columns))
            )

            head.append(index_header_row)

        body = []
        for r, idx in enumerate(self.data.index):
            row_es = []
            for c, value in enumerate(rlabels[r]):
                rid = [
                    ROW_HEADING_CLASS,
                    "level{lvl}".format(lvl=c),
                    "row{row}".format(row=r),
                ]
                es = {
                    "type": "th",
                    "is_visible": (_is_visible(r, c, idx_lengths) and not hidden_index),
                    "value": value,
                    "display_value": value,
                    "id": "_".join(rid[1:]),
                    "class": " ".join(rid),
                }
                rowspan = idx_lengths.get((c, r), 0)
                if rowspan > 1:
                    es["attributes"] = [
                        format_attr({"key": "rowspan", "value": rowspan})
                    ]
                row_es.append(es)

            for c, col in enumerate(self.data.columns):
                cs = [DATA_CLASS, "row{row}".format(row=r), "col{col}".format(col=c)]
                cs.extend(cell_context.get("data", {}).get(r, {}).get(c, []))
                formatter = self._display_funcs[(r, c)]
                value = self.data.iloc[r, c]
                row_dict = {
                    "type": "td",
                    "value": value,
                    "class": " ".join(cs),
                    "display_value": formatter(value),
                    "is_visible": (c not in hidden_columns),
                }
                # only add an id if the cell has a style
                if self.cell_ids or not (len(ctx[r, c]) == 1 and ctx[r, c][0] == ""):
                    row_dict["id"] = "_".join(cs[1:])
                row_es.append(row_dict)
                props = []
                for x in ctx[r, c]:
                    # have to handle empty styles like ['']
                    if x.count(":"):
                        props.append(x.split(":"))
                    else:
                        props.append(["", ""])
                cellstyle.append(
                    {
                        "props": props,
                        "selector": "row{row}_col{col}".format(row=r, col=c),
                    }
                )
            body.append(row_es)

        table_attr = self.table_attributes
        use_mathjax = get_option("display.html.use_mathjax")
        if not use_mathjax:
            table_attr = table_attr or ""
            if 'class="' in table_attr:
                table_attr = table_attr.replace('class="', 'class="tex2jax_ignore ')
            else:
                table_attr += ' class="tex2jax_ignore"'

        return dict(
            head=head,
            cellstyle=cellstyle,
            body=body,
            uuid=uuid,
            precision=precision,
            table_styles=table_styles,
            caption=caption,
            table_attributes=table_attr,
        )
예제 #10
0
    def _translate_header(self, blank_class, blank_value, index_name_class,
                          col_heading_class):
        """
        Build each <tr> within table <head>, using the structure:
             +----------------------------+---------------+---------------------------+
             |  index_blanks ...          | column_name_0 |  column_headers (level_0) |
          1) |       ..                   |       ..      |             ..            |
             |  index_blanks ...          | column_name_n |  column_headers (level_n) |
             +----------------------------+---------------+---------------------------+
          2) |  index_names (level_0 to level_n) ...      | column_blanks ...         |
             +----------------------------+---------------+---------------------------+
        """
        # for sparsifying a MultiIndex
        col_lengths = _get_level_lengths(self.columns, self.hidden_columns)

        clabels = self.data.columns.tolist()
        if self.data.columns.nlevels == 1:
            clabels = [[x] for x in clabels]
        clabels = list(zip(*clabels))

        head = []
        # 1) column headers
        for r in range(self.data.columns.nlevels):
            index_blanks = [
                _element("th", blank_class, blank_value, not self.hidden_index)
            ] * (self.data.index.nlevels - 1)

            name = self.data.columns.names[r]
            column_name = [
                _element(
                    "th",
                    f"{blank_class if name is None else index_name_class} level{r}",
                    name if name is not None else blank_value,
                    not self.hidden_index,
                )
            ]

            if clabels:
                column_headers = [
                    _element(
                        "th",
                        f"{col_heading_class} level{r} col{c}",
                        value,
                        _is_visible(c, r, col_lengths),
                        attributes=(f'colspan="{col_lengths.get((r, c), 0)}"'
                                    if col_lengths.get((r, c), 0) > 1 else ""),
                    ) for c, value in enumerate(clabels[r])
                ]
                head.append(index_blanks + column_name + column_headers)

        # 2) index names
        if (self.data.index.names and com.any_not_none(*self.data.index.names)
                and not self.hidden_index):
            index_names = [
                _element(
                    "th",
                    f"{index_name_class} level{c}",
                    blank_value if name is None else name,
                    True,
                ) for c, name in enumerate(self.data.index.names)
            ]

            column_blanks = [
                _element(
                    "th",
                    f"{blank_class} col{c}",
                    blank_value,
                    c not in self.hidden_columns,
                ) for c in range(len(clabels[0]))
            ]
            head.append(index_names + column_blanks)

        return head
예제 #11
0
    def _translate_header(
        self,
        blank_class: str,
        blank_value: str,
        index_name_class: str,
        col_heading_class: str,
        sparsify_cols: bool,
    ):
        """
        Build each <tr> within table <head> as a list

        Using the structure:
             +----------------------------+---------------+---------------------------+
             |  index_blanks ...          | column_name_0 |  column_headers (level_0) |
          1) |       ..                   |       ..      |             ..            |
             |  index_blanks ...          | column_name_n |  column_headers (level_n) |
             +----------------------------+---------------+---------------------------+
          2) |  index_names (level_0 to level_n) ...      | column_blanks ...         |
             +----------------------------+---------------+---------------------------+

        Parameters
        ----------
        blank_class : str
            CSS class added to elements within blank sections of the structure.
        blank_value : str
            HTML display value given to elements within blank sections of the structure.
        index_name_class : str
            CSS class added to elements within the index_names section of the structure.
        col_heading_class : str
            CSS class added to elements within the column_names section of structure.
        sparsify_cols : bool
            Whether column_headers section will add colspan attributes (>1) to elements.

        Returns
        -------
        head : list
            The associated HTML elements needed for template rendering.
        """
        # for sparsifying a MultiIndex
        col_lengths = _get_level_lengths(self.columns, sparsify_cols,
                                         self.hidden_columns)

        clabels = self.data.columns.tolist()
        if self.data.columns.nlevels == 1:
            clabels = [[x] for x in clabels]
        clabels = list(zip(*clabels))

        head = []
        # 1) column headers
        for r in range(self.data.columns.nlevels):
            index_blanks = [
                _element("th", blank_class, blank_value, not self.hidden_index)
            ] * (self.data.index.nlevels - 1)

            name = self.data.columns.names[r]
            column_name = [
                _element(
                    "th",
                    f"{blank_class if name is None else index_name_class} level{r}",
                    name if name is not None else blank_value,
                    not self.hidden_index,
                )
            ]

            if clabels:
                column_headers = [
                    _element(
                        "th",
                        f"{col_heading_class} level{r} col{c}",
                        value,
                        _is_visible(c, r, col_lengths),
                        attributes=(f'colspan="{col_lengths.get((r, c), 0)}"'
                                    if col_lengths.get((r, c), 0) > 1 else ""),
                    ) for c, value in enumerate(clabels[r])
                ]
                head.append(index_blanks + column_name + column_headers)

        # 2) index names
        if (self.data.index.names and com.any_not_none(*self.data.index.names)
                and not self.hidden_index):
            index_names = [
                _element(
                    "th",
                    f"{index_name_class} level{c}",
                    blank_value if name is None else name,
                    True,
                ) for c, name in enumerate(self.data.index.names)
            ]

            column_blanks = [
                _element(
                    "th",
                    f"{blank_class} col{c}",
                    blank_value,
                    c not in self.hidden_columns,
                ) for c in range(len(clabels[0]))
            ]
            head.append(index_names + column_blanks)

        return head
예제 #12
0
    def _translate(self):
        """
        Convert the DataFrame in `self.data` and the attrs from `_build_styles`
        into a dictionary of {head, body, uuid, cellstyle}.
        """
        ROW_HEADING_CLASS = "row_heading"
        COL_HEADING_CLASS = "col_heading"
        INDEX_NAME_CLASS = "index_name"

        DATA_CLASS = "data"
        BLANK_CLASS = "blank"
        BLANK_VALUE = "&nbsp;"

        # mapping variables
        ctx = self.ctx  # td css styles from apply() and applymap()
        cell_context = self.cell_context  # td css classes from set_td_classes()
        cellstyle_map: DefaultDict[tuple[CSSPair, ...], list[str]] = defaultdict(list)

        # copied attributes
        hidden_index = self.hidden_index
        hidden_columns = self.hidden_columns

        # construct render dict
        d = {
            "uuid": self.uuid,
            "table_styles": _format_table_styles(self.table_styles or []),
            "caption": self.caption,
        }

        # for sparsifying a MultiIndex
        idx_lengths = _get_level_lengths(self.index)
        col_lengths = _get_level_lengths(self.columns, hidden_columns)

        n_rlvls = self.data.index.nlevels
        n_clvls = self.data.columns.nlevels
        rlabels = self.data.index.tolist()
        clabels = self.data.columns.tolist()

        if n_rlvls == 1:
            rlabels = [[x] for x in rlabels]
        if n_clvls == 1:
            clabels = [[x] for x in clabels]
        clabels = list(zip(*clabels))

        head = []
        for r in range(n_clvls):
            # Blank for Index columns...
            row_es = [
                {
                    "type": "th",
                    "value": BLANK_VALUE,
                    "display_value": BLANK_VALUE,
                    "is_visible": not hidden_index,
                    "class": " ".join([BLANK_CLASS]),
                }
            ] * (n_rlvls - 1)

            # ... except maybe the last for columns.names
            name = self.data.columns.names[r]
            cs = [
                BLANK_CLASS if name is None else INDEX_NAME_CLASS,
                f"level{r}",
            ]
            name = BLANK_VALUE if name is None else name
            row_es.append(
                {
                    "type": "th",
                    "value": name,
                    "display_value": name,
                    "class": " ".join(cs),
                    "is_visible": not hidden_index,
                }
            )

            if clabels:
                for c, value in enumerate(clabels[r]):
                    es = {
                        "type": "th",
                        "value": value,
                        "display_value": value,
                        "class": f"{COL_HEADING_CLASS} level{r} col{c}",
                        "is_visible": _is_visible(c, r, col_lengths),
                    }
                    colspan = col_lengths.get((r, c), 0)
                    if colspan > 1:
                        es["attributes"] = f'colspan="{colspan}"'
                    row_es.append(es)
                head.append(row_es)

        if (
            self.data.index.names
            and com.any_not_none(*self.data.index.names)
            and not hidden_index
        ):
            index_header_row = []

            for c, name in enumerate(self.data.index.names):
                cs = [INDEX_NAME_CLASS, f"level{c}"]
                name = "" if name is None else name
                index_header_row.append(
                    {"type": "th", "value": name, "class": " ".join(cs)}
                )

            index_header_row.extend(
                [
                    {
                        "type": "th",
                        "value": BLANK_VALUE,
                        "class": " ".join([BLANK_CLASS, f"col{c}"]),
                    }
                    for c in range(len(clabels[0]))
                    if c not in hidden_columns
                ]
            )

            head.append(index_header_row)
        d.update({"head": head})

        body = []
        for r, row_tup in enumerate(self.data.itertuples()):
            row_es = []
            for c, value in enumerate(rlabels[r]):
                rid = [
                    ROW_HEADING_CLASS,
                    f"level{c}",
                    f"row{r}",
                ]
                es = {
                    "type": "th",
                    "is_visible": (_is_visible(r, c, idx_lengths) and not hidden_index),
                    "value": value,
                    "display_value": value,
                    "id": "_".join(rid[1:]),
                    "class": " ".join(rid),
                }
                rowspan = idx_lengths.get((c, r), 0)
                if rowspan > 1:
                    es["attributes"] = f'rowspan="{rowspan}"'
                row_es.append(es)

            for c, value in enumerate(row_tup[1:]):
                formatter = self._display_funcs[(r, c)]
                row_dict = {
                    "type": "td",
                    "value": value,
                    "display_value": formatter(value),
                    "is_visible": (c not in hidden_columns),
                    "attributes": "",
                }

                # only add an id if the cell has a style
                props: CSSList = []
                if self.cell_ids or (r, c) in ctx:
                    row_dict["id"] = f"row{r}_col{c}"
                    props.extend(ctx[r, c])

                # add custom classes from cell context
                cls = ""
                if (r, c) in cell_context:
                    cls = " " + cell_context[r, c]
                row_dict["class"] = f"{DATA_CLASS} row{r} col{c}{cls}"

                row_es.append(row_dict)
                if props:  # (), [] won't be in cellstyle_map, cellstyle respectively
                    cellstyle_map[tuple(props)].append(f"row{r}_col{c}")
            body.append(row_es)
        d.update({"body": body})

        cellstyle: list[dict[str, CSSList | list[str]]] = [
            {"props": list(props), "selectors": selectors}
            for props, selectors in cellstyle_map.items()
        ]
        d.update({"cellstyle": cellstyle})

        table_attr = self.table_attributes
        use_mathjax = get_option("display.html.use_mathjax")
        if not use_mathjax:
            table_attr = table_attr or ""
            if 'class="' in table_attr:
                table_attr = table_attr.replace('class="', 'class="tex2jax_ignore ')
            else:
                table_attr += ' class="tex2jax_ignore"'
        d.update({"table_attributes": table_attr})

        if self.tooltips:
            d = self.tooltips._translate(self.data, self.uuid, d)

        return d
예제 #13
0
    def _translate_header(
        self,
        blank_class: str,
        blank_value: str,
        index_name_class: str,
        col_heading_class: str,
        sparsify_cols: bool,
        max_cols: int,
        trimmed_col_class: str,
    ):
        """
        Build each <tr> within table <head> as a list

        Using the structure:
             +----------------------------+---------------+---------------------------+
             |  index_blanks ...          | column_name_0 |  column_headers (level_0) |
          1) |       ..                   |       ..      |             ..            |
             |  index_blanks ...          | column_name_n |  column_headers (level_n) |
             +----------------------------+---------------+---------------------------+
          2) |  index_names (level_0 to level_n) ...      | column_blanks ...         |
             +----------------------------+---------------+---------------------------+

        Parameters
        ----------
        blank_class : str
            CSS class added to elements within blank sections of the structure.
        blank_value : str
            HTML display value given to elements within blank sections of the structure.
        index_name_class : str
            CSS class added to elements within the index_names section of the structure.
        col_heading_class : str
            CSS class added to elements within the column_names section of structure.
        sparsify_cols : bool
            Whether column_headers section will add colspan attributes (>1) to elements.
        max_cols : int
            Maximum number of columns to render. If exceeded will contain `...` filler.
        trimmed_col_class : str
            CSS class added to elements within a column including `...` trimmed vals.

        Returns
        -------
        head : list
            The associated HTML elements needed for template rendering.
        """
        # for sparsifying a MultiIndex
        col_lengths = _get_level_lengths(self.columns, sparsify_cols, max_cols,
                                         self.hidden_columns)

        clabels = self.data.columns.tolist(
        )[:max_cols]  # slice to allow trimming
        if self.data.columns.nlevels == 1:
            clabels = [[x] for x in clabels]
        clabels = list(zip(*clabels))

        head = []
        # 1) column headers
        for r in range(self.data.columns.nlevels):
            index_blanks = [
                _element("th", blank_class, blank_value, not self.hidden_index)
            ] * (self.data.index.nlevels - 1)

            name = self.data.columns.names[r]
            column_name = [
                _element(
                    "th",
                    f"{blank_class if name is None else index_name_class} level{r}",
                    name if name is not None else blank_value,
                    not self.hidden_index,
                )
            ]

            if clabels:
                column_headers = [
                    _element(
                        "th",
                        f"{col_heading_class} level{r} col{c}",
                        value,
                        _is_visible(c, r, col_lengths),
                        attributes=(f'colspan="{col_lengths.get((r, c), 0)}"'
                                    if col_lengths.get((r, c), 0) > 1 else ""),
                    ) for c, value in enumerate(clabels[r])
                ]

                if len(self.data.columns) > max_cols:
                    # add an extra column with `...` value to indicate trimming
                    column_headers.append(
                        _element(
                            "th",
                            f"{col_heading_class} level{r} {trimmed_col_class}",
                            "...",
                            True,
                            attributes="",
                        ))
                head.append(index_blanks + column_name + column_headers)

        # 2) index names
        if (self.data.index.names and com.any_not_none(*self.data.index.names)
                and not self.hidden_index):
            index_names = [
                _element(
                    "th",
                    f"{index_name_class} level{c}",
                    blank_value if name is None else name,
                    True,
                ) for c, name in enumerate(self.data.index.names)
            ]

            if len(self.data.columns) <= max_cols:
                blank_len = len(clabels[0])
            else:
                blank_len = len(
                    clabels[0]) + 1  # to allow room for `...` trim col

            column_blanks = [
                _element(
                    "th",
                    f"{blank_class} col{c}",
                    blank_value,
                    c not in self.hidden_columns,
                ) for c in range(blank_len)
            ]
            head.append(index_names + column_blanks)

        return head