Skip to content

Commit bd59050

Browse files
authored
Merge pull request #90 from martinRenou/from_dataframe_dtype_int
Fix integer formatting when loading numpy arrays
2 parents 84508e3 + 549bcca commit bd59050

File tree

7 files changed

+48
-31
lines changed

7 files changed

+48
-31
lines changed

ipysheet/easy.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def current():
6969

7070
def cell(row, column, value=0., type=None, color=None, background_color=None,
7171
font_style=None, font_weight=None, style=None, label_left=None, choice=None,
72-
read_only=False, numeric_format='0.[000]', date_format='YYYY/MM/DD', renderer=None, **kwargs):
72+
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, **kwargs):
7373
"""Adds a new `Cell` widget to the current sheet
7474
7575
Parameters
@@ -124,7 +124,7 @@ def cell(row, column, value=0., type=None, color=None, background_color=None,
124124

125125

126126
def row(row, value, type=None, column_start=0, column_end=None, choice=None,
127-
read_only=False, numeric_format='0.[000]', date_format='YYYY/MM/DD', renderer=None,
127+
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None,
128128
color=None, background_color=None, font_style=None, font_weight=None, **kwargs):
129129
"""Create a CellRange widget, representing multiple cells in a sheet, in a horizontal column
130130
@@ -150,7 +150,7 @@ def row(row, value, type=None, column_start=0, column_end=None, choice=None,
150150

151151

152152
def column(column, value, type=None, row_start=0, row_end=None, choice=None,
153-
read_only=False, numeric_format='0.[000]', date_format='YYYY/MM/DD', renderer=None,
153+
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None,
154154
color=None, background_color=None, font_style=None, font_weight=None, **kwargs):
155155
"""Create a CellRange widget, representing multiple cells in a sheet, in a vertical column
156156
@@ -178,7 +178,7 @@ def column(column, value, type=None, row_start=0, row_end=None, choice=None,
178178

179179
def cell_range(value, row_start=0, column_start=0, row_end=None, column_end=None, transpose=False,
180180
squeeze_row=False, squeeze_column=False, type=None, choice=None,
181-
read_only=False, numeric_format='0.[000]', date_format='YYYY/MM/DD', renderer=None, style=None,
181+
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, style=None,
182182
color=None, background_color=None, font_style=None, font_weight=None, **kwargs):
183183
"""Create a CellRange widget, representing multiple cells in a sheet, in a horizontal column
184184

ipysheet/numpy_loader.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .easy import sheet, column, cell_range
2-
from .utils import extract_data
2+
from .utils import extract_data, get_cell_type, get_cell_numeric_format
33

44

55
def from_array(array):
@@ -30,11 +30,16 @@ def from_array(array):
3030
rows = array.shape[0]
3131
columns = 1 if len(array.shape) == 1 else array.shape[1]
3232

33+
kwargs = {
34+
'numeric_format': get_cell_numeric_format(array.dtype),
35+
'type': get_cell_type(array.dtype)
36+
}
37+
3338
out_sheet = sheet(rows=rows, columns=columns)
3439
if columns == 1:
35-
column(0, array)
40+
column(0, array, **kwargs)
3641
else:
37-
cell_range(array)
42+
cell_range(array, **kwargs)
3843
return out_sheet
3944

4045

ipysheet/pandas_loader.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
from .sheet import Cell, Sheet
2-
from .utils import extract_data
3-
4-
5-
def _get_cell_type(dt):
6-
# TODO Differentiate integer and float? Using custom renderers and
7-
# validators for integers?
8-
# Add support for void type from NumPy?
9-
# See https://handsontable.com/docs/6.2.2/tutorial-cell-types.html
10-
return {
11-
'b': 'checkbox',
12-
'i': 'numeric',
13-
'u': 'numeric',
14-
'f': 'numeric',
15-
'm': 'numeric',
16-
'M': 'date',
17-
'S': 'text',
18-
'U': 'text'
19-
}.get(dt.kind, 'text')
2+
from .utils import extract_data, get_cell_numeric_format, get_cell_type
203

214

225
def _format_date(date):
@@ -76,7 +59,8 @@ def from_dataframe(dataframe):
7659
row_end=len(rows) - 1,
7760
column_start=idx,
7861
column_end=idx,
79-
type=_get_cell_type(arr.dtype),
62+
type=get_cell_type(arr.dtype),
63+
numeric_format=get_cell_numeric_format(arr.dtype),
8064
squeeze_row=False,
8165
squeeze_column=True
8266
))

ipysheet/sheet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class Cell(widgets.Widget):
3030
squeeze_column = Bool(True).tag(sync=True)
3131
transpose = Bool(False).tag(sync=True)
3232
choice = List(Unicode(), allow_none=True, default_value=None).tag(sync=True)
33-
numeric_format = Unicode('0.[000]', allow_none=True).tag(sync=True)
33+
numeric_format = Unicode('0.000', allow_none=True).tag(sync=True)
3434
date_format = Unicode('YYYY/MM/DD', allow_none=True).tag(sync=True)
3535

3636
@traitlets.validate('value')

ipysheet/test_all.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,25 +434,29 @@ def test_from_dataframe():
434434
'C': pd.Series(1, index=list(range(4)), dtype='float32'),
435435
'D': np.array([False, True, False, False], dtype='bool'),
436436
'S': pd.Categorical(["test", "train", "test", "train"]),
437-
'T': 'foo'})
437+
'T': 'foo',
438+
'X': np.array([0, 3, 9, 18])})
438439

439440
df.loc[[0, 2], ['B']] = np.nan
440441

441442
sheet = ipysheet.from_dataframe(df)
442-
assert len(sheet.cells) == 6
443-
assert sheet.column_headers == ['A', 'B', 'C', 'D', 'S', 'T']
443+
assert len(sheet.cells) == 7
444444
assert sheet.cells[0].value == [1., 1., 1., 1.]
445445
assert sheet.cells[0].type == 'numeric'
446446
assert sheet.cells[1].value == [None, '2013/01/02', None, '2013/01/02']
447447
assert sheet.cells[1].type == 'date'
448448
assert sheet.cells[2].value == [1., 1., 1., 1.]
449449
assert sheet.cells[2].type == 'numeric'
450+
assert sheet.cells[2].numeric_format == '0.000'
450451
assert sheet.cells[3].value == [False, True, False, False]
451452
assert sheet.cells[3].type == 'checkbox'
452453
assert sheet.cells[4].value == ['test', 'train', 'test', 'train']
453454
assert sheet.cells[4].type == 'text'
454455
assert sheet.cells[5].value == ['foo', 'foo', 'foo', 'foo']
455456
assert sheet.cells[5].type == 'text'
457+
assert sheet.cells[6].value == [0, 3, 9, 18]
458+
assert sheet.cells[6].type == 'numeric'
459+
assert sheet.cells[6].numeric_format == '0[.]0'
456460

457461

458462
def test_from_to_dataframe():

ipysheet/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,27 @@ def extract_data(sheet):
4747
extract_cell_data(cell, data)
4848

4949
return data
50+
51+
52+
def get_cell_type(dt):
53+
# TODO Differentiate integer and float? Using custom renderers and
54+
# validators for integers?
55+
# Add support for void type from NumPy?
56+
# See https://handsontable.com/docs/6.2.2/tutorial-cell-types.html
57+
return {
58+
'b': 'checkbox',
59+
'i': 'numeric',
60+
'u': 'numeric',
61+
'f': 'numeric',
62+
'm': 'numeric',
63+
'M': 'date',
64+
'S': 'text',
65+
'U': 'text'
66+
}.get(dt.kind, 'text')
67+
68+
69+
def get_cell_numeric_format(dt):
70+
return {
71+
'i': '0[.]0',
72+
'f': '0.000',
73+
}.get(dt.kind)

js/src/sheet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let CellRangeModel = widgets.WidgetModel.extend({
3232
squeeze_row: true,
3333
squeeze_column: true,
3434
transpose: false,
35-
numeric_format: '0.[000]',
35+
numeric_format: '0.000',
3636
date_format: 'YYYY/MM/DD'
3737
});
3838
},

0 commit comments

Comments
 (0)