dataiter 1.1__tar.gz → 1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dataiter-1.1 → dataiter-1.2}/.gitignore +1 -0
- {dataiter-1.1 → dataiter-1.2}/PKG-INFO +1 -1
- {dataiter-1.1 → dataiter-1.2}/dataiter/__init__.py +1 -1
- {dataiter-1.1 → dataiter-1.2}/dataiter/aggregate.py +9 -16
- {dataiter-1.1 → dataiter-1.2}/dataiter/data_frame.py +8 -3
- {dataiter-1.1 → dataiter-1.2}/dataiter/dt.py +13 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_aggregate.py +2 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_data_frame.py +9 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_dt.py +16 -0
- {dataiter-1.1 → dataiter-1.2}/AUTHORS.md +0 -0
- {dataiter-1.1 → dataiter-1.2}/COPYING +0 -0
- {dataiter-1.1 → dataiter-1.2}/README.md +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/deco.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/dtypes.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/geojson.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/io.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/list_of_dicts.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/regex.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/__init__.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_geojson.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_io.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_list_of_dicts.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_regex.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_util.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/test/test_vector.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/util.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/dataiter/vector.py +0 -0
- {dataiter-1.1 → dataiter-1.2}/pyproject.toml +0 -0
|
@@ -25,7 +25,6 @@ import functools
|
|
|
25
25
|
import numpy as np
|
|
26
26
|
import statistics
|
|
27
27
|
|
|
28
|
-
from collections import Counter
|
|
29
28
|
from dataiter import deco
|
|
30
29
|
from dataiter import Vector
|
|
31
30
|
|
|
@@ -403,36 +402,30 @@ def mode(x, *, drop_na=True):
|
|
|
403
402
|
aggregate.group_aware = True
|
|
404
403
|
return aggregate
|
|
405
404
|
x = handle_na(x, drop_na)
|
|
406
|
-
return
|
|
405
|
+
return statistics.mode(x) if len(x) >= 1 else x.na_value
|
|
407
406
|
|
|
408
407
|
@deco.listify
|
|
409
408
|
def mode_apply(x, group, drop_na):
|
|
410
409
|
for xg in yield_groups(x, group, drop_na):
|
|
411
|
-
yield
|
|
410
|
+
yield statistics.mode(xg) if len(xg) >= 1 else None
|
|
412
411
|
|
|
413
412
|
@njit(cache=dataiter.USE_NUMBA_CACHE)
|
|
414
413
|
def mode_apply_numba(x, group, drop_na):
|
|
415
414
|
out = []
|
|
416
415
|
for xg in yield_groups_numba(x, group, drop_na):
|
|
417
416
|
if len(xg) > 0:
|
|
418
|
-
|
|
417
|
+
best_found = xg[0]
|
|
418
|
+
best_count = 1
|
|
419
419
|
for i in range(len(xg)):
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
420
|
+
count = np.sum(xg == xg[i])
|
|
421
|
+
if count > best_count:
|
|
422
|
+
best_found = xg[i]
|
|
423
|
+
best_count = count
|
|
424
|
+
out.append(best_found)
|
|
424
425
|
else:
|
|
425
426
|
out.append(None)
|
|
426
427
|
return out
|
|
427
428
|
|
|
428
|
-
def mode1(x):
|
|
429
|
-
try:
|
|
430
|
-
return statistics.mode(x)
|
|
431
|
-
except statistics.StatisticsError:
|
|
432
|
-
# Python < 3.8 with several elements tied for mode.
|
|
433
|
-
# Return the first encountered of the tied elements.
|
|
434
|
-
return Counter(x).most_common(1)[0][0]
|
|
435
|
-
|
|
436
429
|
@composite
|
|
437
430
|
def nth(x, index, *, drop_na=False):
|
|
438
431
|
"""
|
|
@@ -396,7 +396,12 @@ class DataFrame(dict):
|
|
|
396
396
|
>>> data = di.read_csv("data/listings.csv")
|
|
397
397
|
>>> data.count("hood")
|
|
398
398
|
"""
|
|
399
|
-
|
|
399
|
+
stat = self.copy().group_by(*colnames).aggregate(_n_=dataiter.count())
|
|
400
|
+
if (name := "n") in stat:
|
|
401
|
+
while name in stat: name += "_"
|
|
402
|
+
stat = stat.rename(**{name: "n"})
|
|
403
|
+
stat.n = stat.pop("_n_")
|
|
404
|
+
return stat
|
|
400
405
|
|
|
401
406
|
def deepcopy(self):
|
|
402
407
|
"""
|
|
@@ -1258,9 +1263,9 @@ class DataFrame(dict):
|
|
|
1258
1263
|
batch_rows[i] += " "
|
|
1259
1264
|
batch_rows[i] += column[i]
|
|
1260
1265
|
del columns[colname]
|
|
1261
|
-
rows_to_print.append("" if rows_to_print else "
|
|
1266
|
+
rows_to_print.append("" if rows_to_print else "")
|
|
1262
1267
|
rows_to_print += batch_rows
|
|
1263
|
-
rows_to_print.append("
|
|
1268
|
+
rows_to_print.append("")
|
|
1264
1269
|
if max_rows < self.nrow:
|
|
1265
1270
|
rows_to_print.append(f"... {self.nrow} rows total")
|
|
1266
1271
|
return "\n".join(rows_to_print)
|
|
@@ -74,6 +74,19 @@ def hour(x):
|
|
|
74
74
|
"""
|
|
75
75
|
return _pull_int(x, lambda y: y.hour)
|
|
76
76
|
|
|
77
|
+
def isoformat(x):
|
|
78
|
+
"""
|
|
79
|
+
Return datetime `x` as a string in ISO 8601 format.
|
|
80
|
+
|
|
81
|
+
For dates, return `YYYY-MM-DD`, for datetimes `YYYY-MM-DDTHH:MM:SS.ffffff`.
|
|
82
|
+
|
|
83
|
+
>>> x = dt.new([dt.today()])
|
|
84
|
+
>>> dt.isoformat(x)
|
|
85
|
+
>>> y = dt.new([dt.now()])
|
|
86
|
+
>>> dt.isoformat(y)
|
|
87
|
+
"""
|
|
88
|
+
return _pull_str(x, lambda x: x.isoformat())
|
|
89
|
+
|
|
77
90
|
def isoweek(x):
|
|
78
91
|
"""
|
|
79
92
|
Extract ISO 8601 week from datetime `x`.
|
|
@@ -229,6 +229,15 @@ class TestDataFrame:
|
|
|
229
229
|
assert stat.hood.equal(data.hood.unique().sort())
|
|
230
230
|
assert stat.n.sum() == data.nrow
|
|
231
231
|
|
|
232
|
+
def test_count_n_exists(self):
|
|
233
|
+
data = test.data_frame("listings.csv")
|
|
234
|
+
stat1 = data.count("zipcode")
|
|
235
|
+
stat2 = data.count("zipcode").count("n")
|
|
236
|
+
assert stat1.colnames == ["zipcode", "n"]
|
|
237
|
+
assert stat2.colnames == ["n_", "n"]
|
|
238
|
+
assert stat2.nrow == len(stat1.n.unique())
|
|
239
|
+
assert sum(stat2.n) == stat1.nrow
|
|
240
|
+
|
|
232
241
|
def test_deepcopy(self):
|
|
233
242
|
orig = test.data_frame("vehicles.csv")
|
|
234
243
|
data = orig.copy()
|
|
@@ -62,6 +62,22 @@ class TestDT:
|
|
|
62
62
|
a = dt.new(["2022-10-15T12:34:56", NaT])
|
|
63
63
|
assert dt.hour(a).tolist() == [12, None]
|
|
64
64
|
|
|
65
|
+
def test_isoformat_date(self):
|
|
66
|
+
a = np.array(["2022-10-15", NaT], np.datetime64)
|
|
67
|
+
assert dt.isoformat(a).tolist() == ["2022-10-15", None]
|
|
68
|
+
|
|
69
|
+
def test_isoformat_date_scalar(self):
|
|
70
|
+
x = np.datetime64("2022-10-15")
|
|
71
|
+
assert dt.isoformat(x) == "2022-10-15"
|
|
72
|
+
|
|
73
|
+
def test_isoformat_datetime(self):
|
|
74
|
+
a = np.array(["2022-10-15T12:34:56.789", NaT], np.datetime64)
|
|
75
|
+
assert dt.isoformat(a).tolist() == ["2022-10-15T12:34:56.789000", None]
|
|
76
|
+
|
|
77
|
+
def test_isoformat_datetime_scalar(self):
|
|
78
|
+
x = np.datetime64("2022-10-15T12:34:56.789")
|
|
79
|
+
assert dt.isoformat(x) == "2022-10-15T12:34:56.789000"
|
|
80
|
+
|
|
65
81
|
def test_isoweek(self):
|
|
66
82
|
a = dt.new(["2022-10-15", NaT])
|
|
67
83
|
assert dt.isoweek(a).tolist() == [41, None]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|