{"action":"created","comment":{"url":"https://api.github.com/repos/ironmussa/Optimus/pulls/comments/211773281","pull_request_review_id":148267330,"id":211773281,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxMTc3MzI4MQ==","diff_hunk":"@@ -0,0 +1,1321 @@\n+import builtins\n+import re\n+import string\n+import unicodedata\n+from fastnumbers import fast_float\n+from functools import reduce\n+\n+from multipledispatch import dispatch\n+from pyspark.ml.feature import Imputer, QuantileDiscretizer\n+from pyspark.ml.feature import VectorAssembler\n+from pyspark.ml.linalg import Vectors, VectorUDT\n+from pyspark.sql import DataFrame\n+from pyspark.sql import functions as F\n+from pyspark.sql.functions import Column\n+\n+from optimus.functions import abstract_udf as audf, concat\n+from optimus.functions import filter_row_by_data_type as fbdt\n+from optimus.helpers.checkit \\\n+    import is_num_or_str, is_list, is_, is_tuple, is_list_of_dataframes, is_list_of_tuples, \\\n+    is_function, is_one_element, is_type, is_int, is_dict, is_str\n+# Helpers\n+from optimus.helpers.constants import *\n+from optimus.helpers.decorators import add_attr\n+from optimus.helpers.functions \\\n+    import validate_columns_names, parse_columns, collect_as_dict, format_dict, \\\n+    tuple_to_dict, val_to_list, filter_list, get_spark_dtypes_object\n+from optimus.helpers.raiseit import RaiseIfNot\n+from optimus.profiler.functions import bucketizer\n+from optimus.profiler.functions import create_buckets\n+\n+\n+def cols(self):\n+    @add_attr(cols)\n+    @dispatch(str, object)\n+    def append(col_name=None, value=None):\n+        \"\"\"\n+        Append a column to a Dataframe\n+        :param col_name: Name of the new column\n+        :param value: List of data values\n+        :return:\n+        \"\"\"\n+\n+        def lit_array(value):\n+            temp = []\n+            for v in value:\n+                temp.append(F.lit(v))\n+            return F.array(temp)\n+\n+        df = self\n+\n+        if is_num_or_str(value):\n+            value = F.lit(value)\n+        elif is_list(value):\n+            value = lit_array(value)\n+        elif is_tuple(value):\n+            value = lit_array(list(value))\n+\n+        if is_(value, Column):\n+            df = df.withColumn(col_name, value)\n+\n+        return df\n+\n+    @add_attr(cols)\n+    @dispatch(list)\n+    def append(cols_values=None):\n+        \"\"\"\n+        Append a column or a Dataframe to a Dataframe\n+        :param cols_values: New Column Names and data values\n+        :type cols_values: List of tuples\n+        :return:\n+        \"\"\"\n+\n+        # Append a dataframe\n+        if is_list_of_dataframes(cols_values):\n+            dfs = cols_values\n+            dfs.insert(0, self)\n+            df_result = concat(dfs, like=\"columns\")\n+\n+        elif is_list_of_tuples(cols_values):\n+            df_result = self\n+            for c in cols_values:\n+                col_name = c[0]\n+                value = c[1]\n+                df_result = df_result.cols.append(col_name, value)\n+\n+        return df_result\n+\n+    @add_attr(cols)\n+    def select(columns=None, regex=None, data_type=None):\n+        \"\"\"\n+        Select columns using index, column name, regex to data type\n+        :param columns:\n+        :param regex:\n+        :param data_type:\n+        :return:\n+        \"\"\"\n+        columns = parse_columns(self, columns, is_regex=regex, filter_by_column_dtypes=data_type)\n+        return self.select(columns)\n+\n+    @add_attr(cols)\n+    def apply_expr(columns, func=None, args=None, filter_col_by_dtypes=None, verbose=True):\n+        \"\"\"\n+        Apply a expression to column.\n+        :param columns: Columns in which the function is going to be applied\n+        :param func: function to be applied\n+        :type func: A plain expression or a function\n+        :param args: Argument passed to the function\n+        :param filter_col_by_dtypes: Only apply the filter to specific type of value ,integer, float, string or bool\n+        :param verbose: Print additional information about\n+        :return: Dataframe\n+        \"\"\"\n+\n+        # It handle if func param is a plain expression or a function returning and expression\n+        def func_col_exp(col_name, attr):\n+            return func\n+\n+        if is_(func, Column):\n+            _func = func_col_exp\n+        else:\n+            _func = func\n+\n+        columns = parse_columns(self, columns, filter_by_column_dtypes=filter_col_by_dtypes, accepts_missing_cols=True)\n+\n+        df = self\n+        for col_name in columns:\n+            df = df.withColumn(col_name, audf(col_name, _func, attrs=args, func_type=\"column_exp\", verbose=verbose))\n+        return df\n+\n+    @add_attr(cols)\n+    def apply(columns, func, func_return_type, args=None, func_type=None, when=None, filter_col_by_dtypes=None,\n+              verbose=True):\n+        \"\"\"\n+        Apply a function using pandas udf or udf if apache arrow is not available\n+        :param columns: Columns in which the function is going to be applied\n+        :param func: Functions to be applied to a columns. The declaration must have always 2 params.\n+            def func(value, args):\n+        :param func_return_type: function return type. This is required by UDF and Pandas UDF.\n+        :param args: Arguments to be passed to the function\n+        :param func_type: pandas_udf or udf. If none try to use pandas udf (Pyarrow needed)\n+        :param when: A expression to better control when the function is going to be apllied\n+        :param filter_col_by_dtypes: Only apply the filter to specific type of value ,integer, float, string or bool\n+        :param verbose: Print additional information about\n+        :return: DataFrame\n+        \"\"\"\n+\n+        columns = parse_columns(self, columns, filter_by_column_dtypes=filter_col_by_dtypes, accepts_missing_cols=True)\n+\n+        df = self\n+\n+        def expr(_when):\n+            main_query = audf(c, func, func_return_type, args, func_type, verbose=verbose)\n+            if when is not None:\n+                # Use the data type to filter the query\n+                main_query = F.when(_when, main_query).otherwise(F.col(c))\n+\n+            return main_query\n+\n+        for c in columns:\n+            df = df.withColumn(c, expr(when))\n+        return df\n+\n+    @add_attr(cols)\n+    def apply_by_dtypes(columns, func, func_return_type, args=None, func_type=None, data_type=None):\n+        \"\"\"\n+        Apply a function using pandas udf or udf if apache arrow is not available\n+        :param columns: Columns in which the function is going to be applied\n+        :param func: Functions to be applied to a columns\n+        :param func_return_type\n+        :param args:\n+        :param func_type: pandas_udf or udf. If none try to use pandas udf (Pyarrow needed)\n+        :param data_type:\n+        :return:\n+        \"\"\"\n+        columns = parse_columns(self, columns)\n+\n+        for c in columns:\n+            df = self.cols.apply(c, func, func_return_type, args=args, func_type=func_type,\n+                                 when=fbdt(c, data_type))\n+        return df\n+\n+    @add_attr(cols)\n+    @dispatch(object, object)\n+    def rename(columns_old_new=None, func=None):\n+        \"\"\"\"\n+        Changes the name of a column(s) dataFrame.\n+        :param columns_old_new: List of tuples. Each tuple has de following form: (oldColumnName, newColumnName).\n+        :param func: can be lower, upper or any string transformation function\n+        \"\"\"\n+\n+        df = self\n+        # Apply a transformation function\n+        if is_function(func):\n+            exprs = [F.col(c).alias(func(c)) for c in df.columns]\n+            df = df.select(exprs)\n+        elif is_list_of_tuples(columns_old_new):\n+            # Check that the 1st element in the tuple is a valid set of columns\n+\n+            validate_columns_names(self, columns_old_new)\n+            for c in columns_old_new:\n+                old_col_name = c[0]\n+                if is_str(old_col_name):\n+                    df = df.withColumnRenamed(old_col_name, c[1])\n+                elif is_int(old_col_name):\n+                    df = df.withColumnRenamed(self.schema.names[old_col_name], c[1])\n+\n+        return df\n+\n+    @add_attr(cols)\n+    @dispatch(list)\n+    def rename(columns_old_new=None):\n+        return rename(columns_old_new, None)\n+\n+    @add_attr(cols)\n+    @dispatch(object)\n+    def rename(func=None):\n+        return rename(None, func)\n+\n+    @add_attr(cols)\n+    @dispatch(str, str, object)\n+    def rename(old_column, new_column, func=None):\n+        return rename([(old_column, new_column)], func)\n+\n+    @add_attr(cols)\n+    @dispatch(str, str)\n+    def rename(old_column, new_column):\n+        return rename([(old_column, new_column)], None)\n+\n+    def _cast(cols, args):\n+        \"\"\"\n+        Helper function to support the multiple params implementation\n+        :param cols:\n+        :param args:\n+        :return:\n+        \"\"\"\n+\n+        # assert validate_columns_names(self, cols_and_types, 0)\n+        # cols, attrs = parse_columns(self, cols_and_dtypes, get_args=True)\n+\n+        # if parse_spark_dtypes(attr[0])\n+        def cast_factory(cls):\n+\n+            # Parse standard data types\n+            if get_spark_dtypes_object(cls):\n+                func_type = \"column_exp\"\n+\n+                def cast_to_vectors(col_name, attr):\n+                    return F.col(col_name).cast(get_spark_dtypes_object(cls))\n+\n+                func_return_type = None\n+\n+            # Parse to Vector\n+            elif is_type(cls, Vectors):\n+                func_type = \"udf\"\n+\n+                def cast_to_vectors(val, attr):\n+                    return Vectors.dense(val)\n+\n+                func_return_type = VectorUDT()\n+\n+            # Add here any other parse you want\n+            else:\n+                RaiseIfNot.value_error(cls)\n+\n+            return func_return_type, cast_to_vectors, func_type\n+\n+        df = self\n+        for col, args in zip(cols, args):\n+            return_type, func, func_type = cast_factory(args[0])\n+            df = df.withColumn(col, audf(col, func,\n+                                         func_return_type=return_type,\n+                                         attrs=args[0],\n+                                         func_type=func_type, verbose=False)\n+                               )\n+        return df\n+\n+    @add_attr(cols)\n+    @dispatch(list)\n+    def cast(col_and_dtype):\n+        \"\"\"\n+        Cast multiple columns to a specific datatype\n+        List of tuples of column names and types to be casted. This variable should have the\n+                following structure:\n+\n+                colsAndTypes = [('columnName1', 'integer'), ('columnName2', 'float'), ('columnName3', 'string')]\n+\n+                The first parameter in each tuple is the column name, the second is the final datatype of column after\n+                the transformation is made.\n+\n+        :param col_and_dtype: Columns to be casted and new data types\n+        :return:\n+        \"\"\"\n+        cols, attrs = parse_columns(self, col_and_dtype, get_args=True)\n+        return _cast(cols, attrs)\n+\n+    @add_attr(cols)\n+    @dispatch((list, str), object)\n+    def cast(columns, dtype):\n+        \"\"\"\n+        Cast a column or a list of columns to a specific datatype\n+        :param columns: Columns names to be casted\n+        :param dtype: final data type\n+        :return: Spark DataFrame\n+        \"\"\"\n+\n+        cols = parse_columns(self, columns)\n+        attrs = []\n+        for _ in builtins.range(0, len(cols)):\n+            attrs.append((dtype,))\n+\n+        return _cast(cols, attrs)\n+\n+    @add_attr(cols)\n+    @add_attr(cols)\n+    def astype(*args, **kwargs):\n+        return cast(*args, **kwargs)\n+\n+    @add_attr(cols)\n+    def move(column, position, ref_col):\n+        \"\"\"\n+        Move a column to specific position\n+        :param column: Column to be moved\n+        :param ref_col: Column taken as reference\n+        :param position: Column new position. Accepts 'after' or 'before'\n+        :return: Spark DataFrame\n+        \"\"\"\n+        # Check that column is a string or a list\n+        column = parse_columns(self, column)\n+        ref_col = parse_columns(self, ref_col)\n+\n+        # Asserting if position is 'after' or 'before'\n+        assert (position == 'after') or (\n+                position == 'before'), \"Error: Position parameter only can be 'after' or 'before' actually\" % position\n+\n+        # Get dataframe columns\n+        columns = self.columns\n+\n+        # Get source and reference column index position\n+\n+        new_index = columns.index(ref_col[0])\n+        old_index = columns.index(column[0])\n+\n+        # if position is 'after':\n+        if position == 'after':\n+            # Check if the movement is from right to left:\n+            if new_index >= old_index:\n+                columns.insert(new_index, columns.pop(old_index))  # insert and delete a element\n+            else:  # the movement is form left to right:\n+                columns.insert(new_index + 1, columns.pop(old_index))\n+        else:  # If position if before:\n+            if new_index[0] >= old_index:  # Check if the movement if from right to left:\n+                columns.insert(new_index - 1, columns.pop(old_index))\n+            elif new_index[0] < old_index:  # Check if the movement if from left to right:\n+                columns.insert(new_index, columns.pop(old_index))\n+\n+        return self[columns]\n+\n+    @add_attr(cols)\n+    def keep(columns=None, regex=None):\n+        \"\"\"\n+        Only keep the columns specified\n+        :param columns: Columns to Keep in the dataFrame\n+        :param regex: Regular expression to filter\n+        :return: Spark DataFrame\n+        \"\"\"\n+\n+        if regex:\n+            r = re.compile(regex)\n+            columns = list((r.match, self.columns))\n+\n+        columns = parse_columns(self, columns)\n+        return self.select(*columns)\n+\n+    @add_attr(cols)\n+    # TODO: Create a function to sort by datatype?\n+    def sort(order=\"asc\"):\n+        \"\"\"\n+        Sort dataframes columns asc or desc\n+        :param order: 'asc' or 'desc' accepted\n+        :return: Spark DataFrame\n+        \"\"\"\n+\n+        if order == \"asc\":\n+            sorted_col_names = sorted(self.columns)\n+        elif order == \"desc\":\n+            sorted_col_names = sorted(self.columns, reverse=True)\n+        else:\n+            RaiseIfNot.value_error(order, [\"asc\", \"desc\"])\n+\n+        return self.select(sorted_col_names)\n+\n+    @add_attr(cols)\n+    def drop(columns=None, regex=None, data_type=None):\n+        \"\"\"\n+        Drop a list of columns\n+        :param columns: Columns to be dropped\n+        :param regex: Regex expression to select the columns\n+        :param data_type:\n+        :return:\n+        \"\"\"\n+        df = self\n+        if regex:\n+            r = re.compile(regex)\n+            columns = list((r.match, self.columns))\n+\n+        columns = parse_columns(self, columns, filter_by_column_dtypes=data_type)\n+\n+        for column in columns:\n+            df = df.drop(column)\n+        return df\n+\n+    @add_attr(cols)\n+    def _exprs(funcs, columns):\n+        \"\"\"\n+        Helper function to apply multiple columns expression to multiple columns\n+        :param funcs: Aggregation functions from Apache Spark\n+        :param columns: list or string of columns names or a .\n+        :return:\n+        \"\"\"\n+\n+        def parse_col_names_funcs_to_keys(data):\n+            \"\"\"\n+            Helper function that return a formatted json with function:value inside columns. Transform from\n+            {'max_antiguedad_anos': 15,\n+            'max_m2_superficie_construida': 1800000,\n+            'min_antiguedad_anos': 2,\n+            'min_m2_superficie_construida': 20}\n+\n+            to\n+\n+            {'m2_superficie_construida': {'min': 20, 'max': 1800000}, 'antiguedad_anos': {'min': 2, 'max': 15}}\n+\n+            :param data: json data\n+            :return: json\n+            \"\"\"\n+            functions_array = [\"min\", \"max\", \"stddev\", \"kurtosis\", \"mean\", \"skewness\", \"sum\", \"variance\",\n+                               \"approx_count_distinct\", \"na\", \"zeros\", \"percentile\"]\n+            result = {}\n+            if is_dict(data):\n+                for k, v in data.items():\n+                    for f in functions_array:\n+                        temp_func_name = f + \"_\"\n+                        if k.startswith(temp_func_name):\n+                            _col_name = k[len(temp_func_name):]\n+                            result.setdefault(_col_name, {})[f] = v\n+                return result\n+            else:\n+                return data\n+\n+        columns = parse_columns(self, columns)\n+\n+        # Ensure that is a list\n+        funcs = val_to_list(funcs)\n+\n+        df = self\n+\n+        # Parse the columns to float. Seems that spark can handle some aggregation with string columns giving\n+        # unexpected results\n+        # df = df.cols.cast(columns, \"float\")\n+\n+        # Create a Column Expression for every column\n+        exprs = []\n+        for col_name in columns:\n+            for func in funcs:\n+                exprs.append(func(col_name).alias(func.__name__ + \"_\" + col_name))\n+\n+        return (\n+            parse_col_names_funcs_to_keys(\n+                format_dict(\n+                    collect_as_dict(\n+                        df.agg(*exprs).collect())\n+                )\n+            )\n+        )\n+\n+    # Quantile statistics\n+    @add_attr(cols)\n+    def min(columns):\n+        \"\"\"\n+        Return the min value from a column dataframe\n+        :param columns: '*', list of columns names or a single column name.\n+        :return:\n+        \"\"\"\n+        return _exprs(F.min, columns)\n+\n+    @add_attr(cols)\n+    def max(columns):\n+        \"\"\"\n+        Return the max value from a column dataframe\n+        :param columns: '*', list of columns names or a single column name.\n+        :return:\n+        \"\"\"\n+        return _exprs(F.max, columns)\n+\n+    @add_attr(cols)\n+    def range(columns):","path":"optimus/dataframe/columns.py","position":495,"original_position":495,"commit_id":"5a7a46d00ab9d273a8cc33d9a8cedae17f6f7beb","original_commit_id":"5a7a46d00ab9d273a8cc33d9a8cedae17f6f7beb","user":{"login":"codacy-bot","id":19940114,"node_id":"MDQ6VXNlcjE5OTQwMTE0","avatar_url":"https://avatars1.githubusercontent.com/u/19940114?v=4","gravatar_id":"","url":"https://api.github.com/users/codacy-bot","html_url":"https://github.com/codacy-bot","followers_url":"https://api.github.com/users/codacy-bot/followers","following_url":"https://api.github.com/users/codacy-bot/following{/other_user}","gists_url":"https://api.github.com/users/codacy-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/codacy-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codacy-bot/subscriptions","organizations_url":"https://api.github.com/users/codacy-bot/orgs","repos_url":"https://api.github.com/users/codacy-bot/repos","events_url":"https://api.github.com/users/codacy-bot/events{/privacy}","received_events_url":"https://api.github.com/users/codacy-bot/received_events","type":"User","site_admin":false},"body":"![Codacy](https://app.codacy.com/assets/images/favicon.png) Issue found: [Redefining built-in 'range'](https://app.codacy.com/app/favio.vazquezp/Optimus/pullRequest?prid=2013067)","created_at":"2018-08-21T21:57:12Z","updated_at":"2018-08-21T21:57:13Z","html_url":"https://github.com/ironmussa/Optimus/pull/290#discussion_r211773281","pull_request_url":"https://api.github.com/repos/ironmussa/Optimus/pulls/290","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/comments/211773281"},"html":{"href":"https://github.com/ironmussa/Optimus/pull/290#discussion_r211773281"},"pull_request":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/290"}}},"pull_request":{"url":"https://api.github.com/repos/ironmussa/Optimus/pulls/290","id":206880005,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA2ODgwMDA1","html_url":"https://github.com/ironmussa/Optimus/pull/290","diff_url":"https://github.com/ironmussa/Optimus/pull/290.diff","patch_url":"https://github.com/ironmussa/Optimus/pull/290.patch","issue_url":"https://api.github.com/repos/ironmussa/Optimus/issues/290","number":290,"state":"open","locked":false,"title":"Optimus version 2 official","user":{"login":"FavioVazquez","id":10162068,"node_id":"MDQ6VXNlcjEwMTYyMDY4","avatar_url":"https://avatars2.githubusercontent.com/u/10162068?v=4","gravatar_id":"","url":"https://api.github.com/users/FavioVazquez","html_url":"https://github.com/FavioVazquez","followers_url":"https://api.github.com/users/FavioVazquez/followers","following_url":"https://api.github.com/users/FavioVazquez/following{/other_user}","gists_url":"https://api.github.com/users/FavioVazquez/gists{/gist_id}","starred_url":"https://api.github.com/users/FavioVazquez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FavioVazquez/subscriptions","organizations_url":"https://api.github.com/users/FavioVazquez/orgs","repos_url":"https://api.github.com/users/FavioVazquez/repos","events_url":"https://api.github.com/users/FavioVazquez/events{/privacy}","received_events_url":"https://api.github.com/users/FavioVazquez/received_events","type":"User","site_admin":false},"body":"@argenisleon working on this and me :)","created_at":"2018-08-08T03:03:03Z","updated_at":"2018-08-21T21:57:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c5dbd99dd03fb492f15ab4dfd2c24d31573ceddd","assignee":{"login":"FavioVazquez","id":10162068,"node_id":"MDQ6VXNlcjEwMTYyMDY4","avatar_url":"https://avatars2.githubusercontent.com/u/10162068?v=4","gravatar_id":"","url":"https://api.github.com/users/FavioVazquez","html_url":"https://github.com/FavioVazquez","followers_url":"https://api.github.com/users/FavioVazquez/followers","following_url":"https://api.github.com/users/FavioVazquez/following{/other_user}","gists_url":"https://api.github.com/users/FavioVazquez/gists{/gist_id}","starred_url":"https://api.github.com/users/FavioVazquez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FavioVazquez/subscriptions","organizations_url":"https://api.github.com/users/FavioVazquez/orgs","repos_url":"https://api.github.com/users/FavioVazquez/repos","events_url":"https://api.github.com/users/FavioVazquez/events{/privacy}","received_events_url":"https://api.github.com/users/FavioVazquez/received_events","type":"User","site_admin":false},"assignees":[{"login":"FavioVazquez","id":10162068,"node_id":"MDQ6VXNlcjEwMTYyMDY4","avatar_url":"https://avatars2.githubusercontent.com/u/10162068?v=4","gravatar_id":"","url":"https://api.github.com/users/FavioVazquez","html_url":"https://github.com/FavioVazquez","followers_url":"https://api.github.com/users/FavioVazquez/followers","following_url":"https://api.github.com/users/FavioVazquez/following{/other_user}","gists_url":"https://api.github.com/users/FavioVazquez/gists{/gist_id}","starred_url":"https://api.github.com/users/FavioVazquez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FavioVazquez/subscriptions","organizations_url":"https://api.github.com/users/FavioVazquez/orgs","repos_url":"https://api.github.com/users/FavioVazquez/repos","events_url":"https://api.github.com/users/FavioVazquez/events{/privacy}","received_events_url":"https://api.github.com/users/FavioVazquez/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":645896927,"node_id":"MDU6TGFiZWw2NDU4OTY5Mjc=","url":"https://api.github.com/repos/ironmussa/Optimus/labels/bug","name":"bug","color":"ee0701","default":true},{"id":647151202,"node_id":"MDU6TGFiZWw2NDcxNTEyMDI=","url":"https://api.github.com/repos/ironmussa/Optimus/labels/documentation","name":"documentation","color":"0052cc","default":false},{"id":645896929,"node_id":"MDU6TGFiZWw2NDU4OTY5Mjk=","url":"https://api.github.com/repos/ironmussa/Optimus/labels/enhancement","name":"enhancement","color":"84b6eb","default":true},{"id":721871911,"node_id":"MDU6TGFiZWw3MjE4NzE5MTE=","url":"https://api.github.com/repos/ironmussa/Optimus/labels/testing","name":"testing","color":"d93f0b","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ironmussa/Optimus/pulls/290/commits","review_comments_url":"https://api.github.com/repos/ironmussa/Optimus/pulls/290/comments","review_comment_url":"https://api.github.com/repos/ironmussa/Optimus/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ironmussa/Optimus/issues/290/comments","statuses_url":"https://api.github.com/repos/ironmussa/Optimus/statuses/5a7a46d00ab9d273a8cc33d9a8cedae17f6f7beb","head":{"label":"ironmussa:new_interface","ref":"new_interface","sha":"5a7a46d00ab9d273a8cc33d9a8cedae17f6f7beb","user":{"login":"ironmussa","id":30134402,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTM0NDAy","avatar_url":"https://avatars2.githubusercontent.com/u/30134402?v=4","gravatar_id":"","url":"https://api.github.com/users/ironmussa","html_url":"https://github.com/ironmussa","followers_url":"https://api.github.com/users/ironmussa/followers","following_url":"https://api.github.com/users/ironmussa/following{/other_user}","gists_url":"https://api.github.com/users/ironmussa/gists{/gist_id}","starred_url":"https://api.github.com/users/ironmussa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ironmussa/subscriptions","organizations_url":"https://api.github.com/users/ironmussa/orgs","repos_url":"https://api.github.com/users/ironmussa/repos","events_url":"https://api.github.com/users/ironmussa/events{/privacy}","received_events_url":"https://api.github.com/users/ironmussa/received_events","type":"Organization","site_admin":false},"repo":{"id":97071697,"node_id":"MDEwOlJlcG9zaXRvcnk5NzA3MTY5Nw==","name":"Optimus","full_name":"ironmussa/Optimus","owner":{"login":"ironmussa","id":30134402,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTM0NDAy","avatar_url":"https://avatars2.githubusercontent.com/u/30134402?v=4","gravatar_id":"","url":"https://api.github.com/users/ironmussa","html_url":"https://github.com/ironmussa","followers_url":"https://api.github.com/users/ironmussa/followers","following_url":"https://api.github.com/users/ironmussa/following{/other_user}","gists_url":"https://api.github.com/users/ironmussa/gists{/gist_id}","starred_url":"https://api.github.com/users/ironmussa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ironmussa/subscriptions","organizations_url":"https://api.github.com/users/ironmussa/orgs","repos_url":"https://api.github.com/users/ironmussa/repos","events_url":"https://api.github.com/users/ironmussa/events{/privacy}","received_events_url":"https://api.github.com/users/ironmussa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ironmussa/Optimus","description":":rocket: Optimus is the missing framework for cleansing (cleaning and much more), pre-processing and exploratory data analysis in a distributed fashion with Apache Spark.","fork":false,"url":"https://api.github.com/repos/ironmussa/Optimus","forks_url":"https://api.github.com/repos/ironmussa/Optimus/forks","keys_url":"https://api.github.com/repos/ironmussa/Optimus/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ironmussa/Optimus/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ironmussa/Optimus/teams","hooks_url":"https://api.github.com/repos/ironmussa/Optimus/hooks","issue_events_url":"https://api.github.com/repos/ironmussa/Optimus/issues/events{/number}","events_url":"https://api.github.com/repos/ironmussa/Optimus/events","assignees_url":"https://api.github.com/repos/ironmussa/Optimus/assignees{/user}","branches_url":"https://api.github.com/repos/ironmussa/Optimus/branches{/branch}","tags_url":"https://api.github.com/repos/ironmussa/Optimus/tags","blobs_url":"https://api.github.com/repos/ironmussa/Optimus/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ironmussa/Optimus/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ironmussa/Optimus/git/refs{/sha}","trees_url":"https://api.github.com/repos/ironmussa/Optimus/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ironmussa/Optimus/statuses/{sha}","languages_url":"https://api.github.com/repos/ironmussa/Optimus/languages","stargazers_url":"https://api.github.com/repos/ironmussa/Optimus/stargazers","contributors_url":"https://api.github.com/repos/ironmussa/Optimus/contributors","subscribers_url":"https://api.github.com/repos/ironmussa/Optimus/subscribers","subscription_url":"https://api.github.com/repos/ironmussa/Optimus/subscription","commits_url":"https://api.github.com/repos/ironmussa/Optimus/commits{/sha}","git_commits_url":"https://api.github.com/repos/ironmussa/Optimus/git/commits{/sha}","comments_url":"https://api.github.com/repos/ironmussa/Optimus/comments{/number}","issue_comment_url":"https://api.github.com/repos/ironmussa/Optimus/issues/comments{/number}","contents_url":"https://api.github.com/repos/ironmussa/Optimus/contents/{+path}","compare_url":"https://api.github.com/repos/ironmussa/Optimus/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ironmussa/Optimus/merges","archive_url":"https://api.github.com/repos/ironmussa/Optimus/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ironmussa/Optimus/downloads","issues_url":"https://api.github.com/repos/ironmussa/Optimus/issues{/number}","pulls_url":"https://api.github.com/repos/ironmussa/Optimus/pulls{/number}","milestones_url":"https://api.github.com/repos/ironmussa/Optimus/milestones{/number}","notifications_url":"https://api.github.com/repos/ironmussa/Optimus/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ironmussa/Optimus/labels{/name}","releases_url":"https://api.github.com/repos/ironmussa/Optimus/releases{/id}","deployments_url":"https://api.github.com/repos/ironmussa/Optimus/deployments","created_at":"2017-07-13T02:31:18Z","updated_at":"2018-08-21T16:20:13Z","pushed_at":"2018-08-21T21:54:08Z","git_url":"git://github.com/ironmussa/Optimus.git","ssh_url":"git@github.com:ironmussa/Optimus.git","clone_url":"https://github.com/ironmussa/Optimus.git","svn_url":"https://github.com/ironmussa/Optimus","homepage":"https://hioptimus.com","size":5104,"stargazers_count":289,"watchers_count":289,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":77,"mirror_url":null,"archived":false,"open_issues_count":11,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":77,"open_issues":11,"watchers":289,"default_branch":"master"}},"base":{"label":"ironmussa:master","ref":"master","sha":"180df064608eca03a2b41a849c59e44624b30928","user":{"login":"ironmussa","id":30134402,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTM0NDAy","avatar_url":"https://avatars2.githubusercontent.com/u/30134402?v=4","gravatar_id":"","url":"https://api.github.com/users/ironmussa","html_url":"https://github.com/ironmussa","followers_url":"https://api.github.com/users/ironmussa/followers","following_url":"https://api.github.com/users/ironmussa/following{/other_user}","gists_url":"https://api.github.com/users/ironmussa/gists{/gist_id}","starred_url":"https://api.github.com/users/ironmussa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ironmussa/subscriptions","organizations_url":"https://api.github.com/users/ironmussa/orgs","repos_url":"https://api.github.com/users/ironmussa/repos","events_url":"https://api.github.com/users/ironmussa/events{/privacy}","received_events_url":"https://api.github.com/users/ironmussa/received_events","type":"Organization","site_admin":false},"repo":{"id":97071697,"node_id":"MDEwOlJlcG9zaXRvcnk5NzA3MTY5Nw==","name":"Optimus","full_name":"ironmussa/Optimus","owner":{"login":"ironmussa","id":30134402,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTM0NDAy","avatar_url":"https://avatars2.githubusercontent.com/u/30134402?v=4","gravatar_id":"","url":"https://api.github.com/users/ironmussa","html_url":"https://github.com/ironmussa","followers_url":"https://api.github.com/users/ironmussa/followers","following_url":"https://api.github.com/users/ironmussa/following{/other_user}","gists_url":"https://api.github.com/users/ironmussa/gists{/gist_id}","starred_url":"https://api.github.com/users/ironmussa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ironmussa/subscriptions","organizations_url":"https://api.github.com/users/ironmussa/orgs","repos_url":"https://api.github.com/users/ironmussa/repos","events_url":"https://api.github.com/users/ironmussa/events{/privacy}","received_events_url":"https://api.github.com/users/ironmussa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ironmussa/Optimus","description":":rocket: Optimus is the missing framework for cleansing (cleaning and much more), pre-processing and exploratory data analysis in a distributed fashion with Apache Spark.","fork":false,"url":"https://api.github.com/repos/ironmussa/Optimus","forks_url":"https://api.github.com/repos/ironmussa/Optimus/forks","keys_url":"https://api.github.com/repos/ironmussa/Optimus/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ironmussa/Optimus/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ironmussa/Optimus/teams","hooks_url":"https://api.github.com/repos/ironmussa/Optimus/hooks","issue_events_url":"https://api.github.com/repos/ironmussa/Optimus/issues/events{/number}","events_url":"https://api.github.com/repos/ironmussa/Optimus/events","assignees_url":"https://api.github.com/repos/ironmussa/Optimus/assignees{/user}","branches_url":"https://api.github.com/repos/ironmussa/Optimus/branches{/branch}","tags_url":"https://api.github.com/repos/ironmussa/Optimus/tags","blobs_url":"https://api.github.com/repos/ironmussa/Optimus/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ironmussa/Optimus/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ironmussa/Optimus/git/refs{/sha}","trees_url":"https://api.github.com/repos/ironmussa/Optimus/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ironmussa/Optimus/statuses/{sha}","languages_url":"https://api.github.com/repos/ironmussa/Optimus/languages","stargazers_url":"https://api.github.com/repos/ironmussa/Optimus/stargazers","contributors_url":"https://api.github.com/repos/ironmussa/Optimus/contributors","subscribers_url":"https://api.github.com/repos/ironmussa/Optimus/subscribers","subscription_url":"https://api.github.com/repos/ironmussa/Optimus/subscription","commits_url":"https://api.github.com/repos/ironmussa/Optimus/commits{/sha}","git_commits_url":"https://api.github.com/repos/ironmussa/Optimus/git/commits{/sha}","comments_url":"https://api.github.com/repos/ironmussa/Optimus/comments{/number}","issue_comment_url":"https://api.github.com/repos/ironmussa/Optimus/issues/comments{/number}","contents_url":"https://api.github.com/repos/ironmussa/Optimus/contents/{+path}","compare_url":"https://api.github.com/repos/ironmussa/Optimus/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ironmussa/Optimus/merges","archive_url":"https://api.github.com/repos/ironmussa/Optimus/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ironmussa/Optimus/downloads","issues_url":"https://api.github.com/repos/ironmussa/Optimus/issues{/number}","pulls_url":"https://api.github.com/repos/ironmussa/Optimus/pulls{/number}","milestones_url":"https://api.github.com/repos/ironmussa/Optimus/milestones{/number}","notifications_url":"https://api.github.com/repos/ironmussa/Optimus/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ironmussa/Optimus/labels{/name}","releases_url":"https://api.github.com/repos/ironmussa/Optimus/releases{/id}","deployments_url":"https://api.github.com/repos/ironmussa/Optimus/deployments","created_at":"2017-07-13T02:31:18Z","updated_at":"2018-08-21T16:20:13Z","pushed_at":"2018-08-21T21:54:08Z","git_url":"git://github.com/ironmussa/Optimus.git","ssh_url":"git@github.com:ironmussa/Optimus.git","clone_url":"https://github.com/ironmussa/Optimus.git","svn_url":"https://github.com/ironmussa/Optimus","homepage":"https://hioptimus.com","size":5104,"stargazers_count":289,"watchers_count":289,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":77,"mirror_url":null,"archived":false,"open_issues_count":11,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":77,"open_issues":11,"watchers":289,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/290"},"html":{"href":"https://github.com/ironmussa/Optimus/pull/290"},"issue":{"href":"https://api.github.com/repos/ironmussa/Optimus/issues/290"},"comments":{"href":"https://api.github.com/repos/ironmussa/Optimus/issues/290/comments"},"review_comments":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/290/comments"},"review_comment":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ironmussa/Optimus/pulls/290/commits"},"statuses":{"href":"https://api.github.com/repos/ironmussa/Optimus/statuses/5a7a46d00ab9d273a8cc33d9a8cedae17f6f7beb"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"codacy-bot"}}