Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .list.astype() to cast list leaves to specified dtype #10693

Merged
merged 4 commits into from Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 47 additions & 9 deletions python/cudf/cudf/core/column/lists.py
Expand Up @@ -299,16 +299,31 @@ def as_string_column(
"""
Create a strings column from a list column
"""
# Convert the leaf child column to strings column
lc = self._transform_leaves(
lambda col, dtype: col.as_string_column(dtype), dtype
)

# Separator strings to match the Python format
separators = as_column([", ", "[", "]"])

# Call libcudf to format the list column
return format_list_column(lc, separators)

def _transform_leaves(self, func, *args, **kwargs):
# return a new list column with the same nested structure
# as ``self``, but with the leaf column transformed
# by applying ``func`` to it

cc: List[ListColumn] = []
c: ColumnBase = self

while isinstance(c, ListColumn):
cc.insert(0, c)
c = c.children[1]
s = c.as_string_column(dtype)

lc = func(c, *args, **kwargs)

# Rebuild the list column replacing just the leaf child
lc = s
for c in cc:
o = c.children[0]
lc = cudf.core.column.ListColumn( # type: ignore
Expand All @@ -319,12 +334,7 @@ def as_string_column(
null_count=c.null_count,
children=(o, lc),
)

# Separator strings to match the Python format
separators = as_column([", ", "[", "]"])

# Call libcudf to format the list column
return format_list_column(lc, separators)
return lc


class ListMethods(ColumnMethods):
Expand Down Expand Up @@ -715,3 +725,31 @@ def concat(self, dropna=True) -> ParentType:
"of nesting"
)
return self._return_or_inplace(result)

def astype(self, dtype):
"""
Return a new list Series with the leaf values casted
to the specified data type.

Parameters
----------
dtype: data type to cast leaves values to

Returns
-------
A new Series of lists

Examples
--------
>>> s = cudf.Series([[1, 2], [3, 4]])
>>> s.dtype
ListDtype(int64)
>>> s2 = s.list.astype("float64")
>>> s2.dtype
ListDtype(float64)
"""
return self._return_or_inplace(
self._column._transform_leaves(
lambda col, dtype: col.astype(dtype), dtype
)
)
12 changes: 12 additions & 0 deletions python/cudf/cudf/tests/test_list.py
Expand Up @@ -759,3 +759,15 @@ def test_listcol_setitem_retain_dtype():
# prior to this fix: https://github.com/rapidsai/cudf/pull/10151/
df2 = df1.copy()
assert df2["a"].dtype == df["a"].dtype


def test_list_astype():
rgsl888prabhu marked this conversation as resolved.
Show resolved Hide resolved
s = cudf.Series([[1, 2], [3, 4]])
s2 = s.list.astype("float64")
assert s2.dtype == cudf.ListDtype("float64")
assert_eq(s.list.leaves.astype("float64"), s2.list.leaves)

s = cudf.Series([[[1, 2], [3]], [[5, 6], None]])
s2 = s.list.astype("string")
assert s2.dtype == cudf.ListDtype(cudf.ListDtype("string"))
assert_eq(s.list.leaves.astype("string"), s2.list.leaves)