From 45bb74c79fdf0e5fe4713b56eceb8ca6cf1c5d4f Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Mon, 15 May 2017 14:31:39 +0300 Subject: [PATCH] initial support of pandas Series (PY-21763) --- .../pydev/_pydevd_bundle/pydevd_vars.py | 56 +++++++++++++++++++ .../python/debugger/PyDebugValue.java | 20 +++---- .../containerview/DataViewStrategy.java | 10 +++- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py b/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py index f3d9d030fd2d..46c27ddf404b 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py @@ -425,6 +425,9 @@ def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format): xml += array_to_xml(array, roffset, coffset, rows, cols, format) elif type_name == 'DataFrame': xml = dataframe_to_xml(array, name, roffset, coffset, rows, cols, format) + elif type_name == 'Series': + xml = series_to_xml(array, name, roffset, 0, rows, 1, format) + else: raise VariableError("Do not know how to convert type %s to table" % (type_name)) @@ -616,3 +619,56 @@ def dataframe_to_xml(df, name, roffset, coffset, rows, cols, format): value = col_formats[col] % value xml += var_to_xml(value, '') return xml + + +def series_to_xml(df, name, roffset, coffset, rows, cols, format): + """ + :type df: pandas.core.frame.DataFrame + :type name: str + :type coffset: int + :type roffset: int + :type rows: int + :type cols: int + :type format: str + + + """ + num_rows = df.shape[0] + xml = '\n' % \ + (name, num_rows, 1) + + if (rows, cols) == (-1, -1): + rows, cols = num_rows, 1 + + rows = min(rows, 100) + dtype = df.dtype.kind + col_bounds = [(df.min(), df.max()) if dtype in "biufc" else (0, 0)] + + df = df.iloc[roffset: roffset + rows] + rows, cols = df.shape[0], 1 + + + xml += "\n" % (rows, cols) + format = format.replace('%', '') + col_formats = [] + + + for col in range(cols): + fmt = format if (dtype == 'f' and format) else array_default_format(dtype) + col_formats.append('%' + fmt) + bounds = col_bounds[col] + + xml += '\n' % \ + (str(col), 1, dtype, fmt, bounds[1], bounds[0]) + for row, label in enumerate(iter(df.axes[0])): + xml += "\n" % \ + (str(row), 1) + xml += "\n" + xml += "\n" % (rows, cols) + for row in range(rows): + xml += "\n" % str(row) + for col in range(cols): + value = df.iat[row] + value = col_formats[col] % value + xml += var_to_xml(value, '') + return xml diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java index 09444ad6d618..4d2d4a9ccdfb 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java @@ -4,12 +4,15 @@ import com.google.common.base.Strings; import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.frame.*; import com.jetbrains.python.debugger.pydev.PyVariableLocator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -17,6 +20,10 @@ import java.util.regex.Pattern; // todo: null modifier for modify modules, class objects etc. public class PyDebugValue extends XNamedValue { private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.pydev.PyDebugValue"); + private static final String DATA_FRAME = "DataFrame"; + private static final String SERIES = "Series"; + private static final Map EVALUATOR_PREFIXES = + ContainerUtil.newHashMap(Pair.create("ndarray", "Array"), Pair.create(DATA_FRAME, DATA_FRAME), Pair.create(SERIES, SERIES)); public static final int MAX_VALUE = 256; public static final String RETURN_VALUES_PREFIX = "__pydevd_ret_val_dict"; @@ -204,23 +211,16 @@ public class PyDebugValue extends XNamedValue { node.setPresentation(getValueIcon(), myType, value, myContainer); } - private boolean isDataFrame() { - return "DataFrame".equals(myType); - } - - private boolean isNdarray() { - return "ndarray".equals(myType); - } - private void setFullValueEvaluator(XValueNode node, String value) { String treeName = getFullTreeName(); - if (!isDataFrame() && !isNdarray()) { + String postfix = EVALUATOR_PREFIXES.get(myType); + if (postfix == null) { if (value.length() >= MAX_VALUE) { node.setFullValueEvaluator(new PyFullValueEvaluator(myFrameAccessor, treeName)); } return; } - String linkText = "...View as " + (isDataFrame() ? "DataFrame" : "Array"); + String linkText = "...View as " + postfix; node.setFullValueEvaluator(new PyNumericContainerValueEvaluator(linkText, myFrameAccessor, treeName)); } diff --git a/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java b/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java index 1eb2678b3715..842781afcbf6 100644 --- a/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java +++ b/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java @@ -29,7 +29,7 @@ import java.util.Set; public abstract class DataViewStrategy { private static class StrategyHolder { - private static final Set STRATEGIES = ContainerUtil.newHashSet(new ArrayViewStrategy(), new DataFrameViewStrategy()); + private static final Set STRATEGIES = ContainerUtil.newHashSet(new ArrayViewStrategy(), new DataFrameViewStrategy(), new DataFrameViewStrategy(), new SeriesViewStrategy()); } public abstract AsyncArrayTableModel createTableModel(int rowCount, int columnCount, @NotNull PyDataViewerPanel panel, @NotNull PyDebugValue debugValue); @@ -53,4 +53,12 @@ public abstract class DataViewStrategy { } return null; } + + private static class SeriesViewStrategy extends DataFrameViewStrategy { + @NotNull + @Override + public String getTypeName() { + return "Series"; + } + } } \ No newline at end of file