<commit_before>from __future__ import absolute_import

import warnings

from ..core.has_props import abstract
from ..core.properties import Any, Bool, ColumnData, Dict, Enum, Instance, Int, JSON, List, Seq, String
from ..model import Model
from ..util.dependencies import import_optional
from ..util.warnings import BokehUserWarning

from .callbacks import Callback

pd = import_optional('pandas')

@abstract
class DataSource(Model):
    ''' A base class for data source types.

    '''

    selected = Dict(String, Dict(String, Any), default={
        '0d': {'glyph': None, 'indices': []},
        '1d': {'indices': []},
        '2d': {}
    }, help="""
    A dict to indicate selected indices on different dimensions on this DataSource. Keys are:

    .. code-block:: python

        # selection information for line and patch glyphs
        '0d' : {
          # the glyph that was selected
          'glyph': None

          # array with the [smallest] index of the segment of the line that was hit
          'indices': []
        }

        # selection for most (point-like) glyphs, except lines and patches
        '1d': {
          # indices of the points included in the selection
          indices: []
        }

        # selection information for multiline and patches glyphs
        '2d': {
          # mapping of indices of the multiglyph to array of glyph indices that were hit
          # e.g. {3: [5, 6], 4, [5]}
        }

    """)

    callback = Instance(Callback, help="""
    A callback to run in the browser whenever the selection is changed.
    """)

@abstract
class ColumnarDataSource(DataSource):
    ''' A base class for data source types, which can be mapped onto
    a columnar format.

    '''

    column_names = List(String, help="""
    An list of names for all the columns in this DataSource.
    """)

class ColumnDataSource(ColumnarDataSource):
    ''' Maps names of columns to sequences or arrays.

    If the ColumnDataSource initializer is called with a single argument that
    is a dict or pandas.DataFrame, that argument is used as the value for the
    "data" attribute. For example::

        ColumnDataSource(mydict) # same as ColumnDataSource(data=mydict)
        ColumnDataSource(df) # same as ColumnDataSource(data=df)

    .. note::
        There is an implicit assumption that all the columns in a
        a given ColumnDataSource have the same length.

    '''

    data = ColumnData(String, Seq(Any), help="""
    Mapping of column names to sequences of data. The data can be, e.g,
    Python lists or tuples, NumPy arrays, etc.
    """).asserts(lambda _, data: len(set(len(x) for x in data.values())) <= 1,
                 lambda: warnings.warn("ColumnDataSource's columns must be of the same length", BokehUserWarning))


    def __init__(self, *args, **kw):
        ''' If called with a single argument that is a dict or
        pandas.DataFrame, treat that implicitly as the "data" attribute.

        '''
        if len(args) == 1 and "data" not in kw:
            kw["data"] = args[0]

        # TODO (bev) invalid to pass args and "data", check and raise exception
        raw_data = kw.pop("data", {})

        if not isinstance(raw_data, dict):
            if pd and isinstance(raw_data, pd.DataFrame):
                raw_data = self._data_from_df(raw_data)
            else:
                raise ValueError("expected a dict or pandas.DataFrame, got %s" % raw_data)
        super(ColumnDataSource, self).__init__(**kw)
        for name, data in raw_data.items():
            self.add(data, name)
<commit_msg>Optimized ColumnDataSource constructor (#5872)<commit_after>from __future__ import absolute_import

import warnings

from ..core.has_props import abstract
from ..core.properties import Any, Bool, ColumnData, Dict, Enum, Instance, Int, JSON, List, Seq, String
from ..model import Model
from ..util.dependencies import import_optional
from ..util.warnings import BokehUserWarning

from .callbacks import Callback

pd = import_optional('pandas')

@abstract
class DataSource(Model):
    ''' A base class for data source types.

    '''

    selected = Dict(String, Dict(String, Any), default={
        '0d': {'glyph': None, 'indices': []},
        '1d': {'indices': []},
        '2d': {}
    }, help="""
    A dict to indicate selected indices on different dimensions on this DataSource. Keys are:

    .. code-block:: python

        # selection information for line and patch glyphs
        '0d' : {
          # the glyph that was selected
          'glyph': None

          # array with the [smallest] index of the segment of the line that was hit
          'indices': []
        }

        # selection for most (point-like) glyphs, except lines and patches
        '1d': {
          # indices of the points included in the selection
          indices: []
        }

        # selection information for multiline and patches glyphs
        '2d': {
          # mapping of indices of the multiglyph to array of glyph indices that were hit
          # e.g. {3: [5, 6], 4, [5]}
        }

    """)

    callback = Instance(Callback, help="""
    A callback to run in the browser whenever the selection is changed.
    """)

@abstract
class ColumnarDataSource(DataSource):
    ''' A base class for data source types, which can be mapped onto
    a columnar format.

    '''

    column_names = List(String, help="""
    An list of names for all the columns in this DataSource.
    """)

class ColumnDataSource(ColumnarDataSource):
    ''' Maps names of columns to sequences or arrays.

    If the ColumnDataSource initializer is called with a single argument that
    is a dict or pandas.DataFrame, that argument is used as the value for the
    "data" attribute. For example::

        ColumnDataSource(mydict) # same as ColumnDataSource(data=mydict)
        ColumnDataSource(df) # same as ColumnDataSource(data=df)

    .. note::
        There is an implicit assumption that all the columns in a
        a given ColumnDataSource have the same length.

    '''

    data = ColumnData(String, Seq(Any), help="""
    Mapping of column names to sequences of data. The data can be, e.g,
    Python lists or tuples, NumPy arrays, etc.
    """).asserts(lambda _, data: len(set(len(x) for x in data.values())) <= 1,
                 lambda: warnings.warn("ColumnDataSource's columns must be of the same length", BokehUserWarning))


    def __init__(self, *args, **kw):
        ''' If called with a single argument that is a dict or
        pandas.DataFrame, treat that implicitly as the "data" attribute.

        '''
        if len(args) == 1 and "data" not in kw:
            kw["data"] = args[0]

        # TODO (bev) invalid to pass args and "data", check and raise exception
        raw_data = kw.pop("data", {})

        if not isinstance(raw_data, dict):
            if pd and isinstance(raw_data, pd.DataFrame):
                raw_data = self._data_from_df(raw_data)
            else:
                raise ValueError("expected a dict or pandas.DataFrame, got %s" % raw_data)
        super(ColumnDataSource, self).__init__(**kw)
        self.column_names[:] = list(raw_data.keys())
        self.data.update(raw_data)

{'fraction_non_alphanumeric': 0.10019482326746451, 'fraction_numerical': 0.004453103256331756, 'mean_word_length': 2.5952976488244124, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4379551', 'n_tokens_mistral': 2018, 'n_tokens_neox': 1937, 'n_words': 779}