Skip to content

Commit 95a32bb

Browse files
author
Xuye (Chris) Qin
authored
[BACKPORT] Implement {DataFrame, Series}.empty (#2155) (#2174)
1 parent 88eadcf commit 95a32bb

File tree

4 files changed

+55
-20
lines changed

4 files changed

+55
-20
lines changed

mars/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import subprocess
1616
import os
1717

18-
version_info = (0, 6, 9)
18+
version_info = (0, 6, 10)
1919
_num_index = max(idx if isinstance(v, int) else 0
2020
for idx, v in enumerate(version_info))
2121
__version__ = '.'.join(map(str, version_info[:_num_index + 1])) + \

mars/dataframe/base/tests/test_base.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,3 +902,26 @@ def a():
902902
df.eval("p, q = a + c")
903903
with self.assertRaises(ValueError):
904904
df.query("p = a + c")
905+
906+
def testEmpty(self):
907+
# for DataFrame
908+
assert from_pandas_df(pd.DataFrame()).empty == pd.DataFrame().empty
909+
assert from_pandas_df(pd.DataFrame({})).empty == pd.DataFrame({}).empty
910+
assert from_pandas_df(pd.DataFrame({'a':[]})).empty == pd.DataFrame({'a':[]}).empty
911+
assert from_pandas_df(pd.DataFrame({'a':[1]})).empty == pd.DataFrame({'a':[1]}).empty
912+
assert from_pandas_df(pd.DataFrame({'a':[1], 'b':[2]})).empty == pd.DataFrame({'a':[1], 'b':[2]}).empty
913+
assert from_pandas_df(pd.DataFrame(np.empty(shape=(4,0)))).empty == pd.DataFrame(np.empty(shape=(4,0))).empty
914+
915+
# for Series
916+
assert from_pandas_series(pd.Series()).empty == pd.Series().empty
917+
assert from_pandas_series(pd.Series({})).empty == pd.Series({}).empty
918+
assert from_pandas_series(pd.Series({'a':[]})).empty == pd.Series({'a':[]}).empty
919+
assert from_pandas_series(pd.Series({'a':[1]})).empty == pd.Series({'a':[1]}).empty
920+
921+
# Maybe fail due to lazy evaluation
922+
with self.assertRaises(ValueError):
923+
a = from_pandas_df(pd.DataFrame(np.random.rand(10, 2)))
924+
assert a[a > 0].empty == True
925+
with self.assertRaises(ValueError):
926+
a = from_pandas_series(pd.Series(np.random.rand(10)))
927+
assert a[a > 0].empty == True

mars/dataframe/core.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,13 @@ def index(self):
881881
def axes(self):
882882
return [self.index]
883883

884+
@property
885+
def empty(self):
886+
shape = getattr(self, '_shape')
887+
if np.any(np.isnan(shape)):
888+
raise ValueError('Tileable object must be executed first')
889+
return shape == (0,)
890+
884891
def to_tensor(self, dtype=None):
885892
from ..tensor.datasource.from_dataframe import from_series
886893
return from_series(self, dtype=dtype)
@@ -1243,6 +1250,13 @@ def index_value(self):
12431250
def columns_value(self):
12441251
return self._columns_value
12451252

1253+
@property
1254+
def empty(self):
1255+
shape = getattr(self, '_shape')
1256+
if np.any(np.isnan(shape)):
1257+
raise ValueError('Tileable object must be executed first')
1258+
return (0 in shape)
1259+
12461260
def to_tensor(self, dtype=None):
12471261
from ..tensor.datasource.from_dataframe import from_dataframe
12481262
return from_dataframe(self, dtype=dtype)

mars/utils.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -198,27 +198,25 @@ def _get_ports_from_netstat():
198198
while True:
199199
p = subprocess.Popen('netstat -a -n -p tcp'.split(), stdout=subprocess.PIPE)
200200
try:
201-
p.wait(5)
202-
break
201+
outs, _ = p.communicate(timeout=5)
202+
outs = to_str(outs).split('\n')
203+
occupied = set()
204+
for line in outs:
205+
if '.' not in line:
206+
continue
207+
for part in line.split():
208+
if '.' in part:
209+
_, port_str = part.rsplit('.', 1)
210+
if port_str == '*':
211+
continue
212+
port = int(port_str)
213+
if LOW_PORT_BOUND <= port <= HIGH_PORT_BOUND:
214+
occupied.add(int(port_str))
215+
break
216+
return occupied
203217
except subprocess.TimeoutExpired:
204-
p.terminate()
205-
continue
206-
occupied = set()
207-
for line in p.stdout:
208-
line = to_str(line)
209-
if '.' not in line:
218+
p.kill()
210219
continue
211-
for part in line.split():
212-
if '.' in part:
213-
_, port_str = part.rsplit('.', 1)
214-
if port_str == '*':
215-
continue
216-
port = int(port_str)
217-
if LOW_PORT_BOUND <= port <= HIGH_PORT_BOUND:
218-
occupied.add(int(port_str))
219-
break
220-
p.stdout.close()
221-
return occupied
222220

223221

224222
def get_next_port(typ=None, occupy=True):

0 commit comments

Comments
 (0)