Skip to content

Commit 9d3fdfd

Browse files
committed
Merge branch 'master' of https://github.com/tinproject/pandas into tinproject-master
Conflicts: doc/source/release.rst
2 parents 11d6e95 + 3efb86e commit 9d3fdfd

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Improvements to existing features
171171
``tupleize_cols`` and ``thousands`` parameters (:issue:`4770`).
172172
- :meth:`~pandas.io.json.json_normalize` is a new method to allow you to create a flat table
173173
from semi-structured JSON data. :ref:`See the docs<io.json_normalize>` (:issue:`1067`)
174+
- ``DataFrame.from_records()`` will now accept generators (:issue:`4910`)
174175

175176
API Changes
176177
~~~~~~~~~~~

pandas/core/frame.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -724,12 +724,17 @@ def from_records(cls, data, index=None, exclude=None, columns=None,
724724

725725
values = [first_row]
726726

727-
i = 1
728-
for row in data:
729-
values.append(row)
730-
i += 1
731-
if i >= nrows:
732-
break
727+
#if unknown length iterable (generator)
728+
if nrows == None:
729+
#consume whole generator
730+
values += list(data)
731+
else:
732+
i = 1
733+
for row in data:
734+
values.append(row)
735+
i += 1
736+
if i >= nrows:
737+
break
733738

734739
if dtype is not None:
735740
data = np.array(values, dtype=dtype)

pandas/tests/test_frame.py

+30
Original file line numberDiff line numberDiff line change
@@ -3739,6 +3739,36 @@ def test_from_records_iterator(self):
37393739
nrows=2)
37403740
assert_frame_equal(df, xp.reindex(columns=['x','y']), check_dtype=False)
37413741

3742+
def test_from_records_tuples_generator(self):
3743+
def tuple_generator(length):
3744+
for i in range(length):
3745+
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
3746+
yield (i, letters[i % len(letters)], i/length)
3747+
3748+
columns_names = ['Integer', 'String', 'Float']
3749+
columns = [[i[j] for i in tuple_generator(10)] for j in range(len(columns_names))]
3750+
data = {'Integer': columns[0], 'String': columns[1], 'Float': columns[2]}
3751+
expected = DataFrame(data, columns=columns_names)
3752+
3753+
generator = tuple_generator(10)
3754+
result = DataFrame.from_records(generator, columns=columns_names)
3755+
assert_frame_equal(result, expected)
3756+
3757+
def test_from_records_lists_generator(self):
3758+
def list_generator(length):
3759+
for i in range(length):
3760+
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
3761+
yield [i, letters[i % len(letters)], i/length]
3762+
3763+
columns_names = ['Integer', 'String', 'Float']
3764+
columns = [[i[j] for i in list_generator(10)] for j in range(len(columns_names))]
3765+
data = {'Integer': columns[0], 'String': columns[1], 'Float': columns[2]}
3766+
expected = DataFrame(data, columns=columns_names)
3767+
3768+
generator = list_generator(10)
3769+
result = DataFrame.from_records(generator, columns=columns_names)
3770+
assert_frame_equal(result, expected)
3771+
37423772
def test_from_records_columns_not_modified(self):
37433773
tuples = [(1, 2, 3),
37443774
(1, 2, 3),

0 commit comments

Comments
 (0)