klonowsk

klonowsk

Having trouble splitting rows using Explorer.DataFrame

Hi,

I’m having trouble figuring out how to take a dataframe, split one of the text cells based on a function, and create new rows with the results, with all other column data duplicated for each row.

I just can’t figure out how to convert the list of text fragments into something that can be expanded into additional rows.

My (naïve) stab at it looks as follows for now:

require Explorer.DataFrame, as: DF
require Explorer.Series, as: S

defmodule MyDF do
  def apply(df, column, new_column, func) do
    series = DF.pull(df, column)
    list = S.to_list(series)

    new_series =
      list
      |> Enum.map(&func.(&1))
      |> S.from_list()

    DF.put(df, new_column, new_series)
  end
end

df = DF.new(
  class: [1, 2, 1, 3],
  text: ["AAA, BBB", "CCC, DDD", "EEE", "FFF, GGG, HHH"]
)

df
|> MyDF.apply("text", "new_text", &String.split(&1, ","))

Resulting in:

#Explorer.DataFrame<
Polars[4 x 3]
class integer [1, 2, 1, 3]
text string [“AAA, BBB”, “CCC, DDD”, “EEE”, “FFF, GGG, HHH”]
new_text list[string] [
[“AAA”, " BBB"],
[“CCC”, " DDD"],
[“EEE”],
[“FFF”, …]
]

But I would like that list of new_text to be spread accross multiple rows.

I’m coming from R+ and tidy/dplyr, where I would do something simple like:

df %>%
  dplyr::rowwise() %>%
  mutate(new_text = parse_text(text))

Thank you

Marked As Solved

billylanchantin

billylanchantin

Whoops! I forgot there was a bug with split which was just fixed last week:

I was on main locally so I didn’t see it. To workaround, you’ll need to do a pipeline like this:

df
|> DF.put("text", S.split(df["text"], ", "))
|> DF.explode("text")

(@bdarla’s approach works too.)

Or you can use main until the next release. Sorry about that!

Also Liked

billylanchantin

billylanchantin

Hi @klonowsk,

If I’ve followed what you’re trying to achieve, I think this works:

require Explorer.DataFrame, as: DF

df = DF.new(
  class: [1, 2, 1, 3],
  text: ["AAA, BBB", "CCC, DDD", "EEE", "FFF, GGG, HHH"]
)

df
|> DF.mutate(text: split(text, ", "))
|> DF.explode("text")
# #Explorer.DataFrame<
#   Polars[8 x 2]
#   class s64 [1, 1, 2, 2, 1, ...]
#   text string ["AAA", "BBB", "CCC", "DDD", "EEE", ...]
# >
bdarla

bdarla

Indeed, it seems that a previous cell in my Livebook allowed the code to run. Please, try the following:

Mix.install([
  {:axon, "~> 0.6"}, 
  {:nx, "~> 0.7"}, 
  {:explorer, "~> 0.8"}, 
  {:kino, "~> 0.12"}
])
require Explorer.DataFrame, as: DF
require Explorer.Series, as: S
text_list = ["AAA, BBB", "CCC, DDD", "EEE", "FFF, GGG, HHH"]
text = S.from_list(text_list)
df = DF.new(
class: [1, 2, 1, 3],
text: text_list
)
split_list = S.split(text, ", ")
df
|> DF.mutate(text: ^split_list)
|> DF.explode(:text)

Last Post!

klonowsk

klonowsk

Yes, all the above solutions work, and yes, I fell for the S.split() issue, however, sourcing from git:main results in far too many dependencies braking, so DF.put("text", S.split(df["text"], ", ")) works just fine for this toy example as well as for my needs as I have my own somewhat more complex text splitting function, which I just modified to return a series lists of the split texts to feed into DF.put(). The more relevant function is DF.explode(), which was missing from the version of the Explorer library I was using. So thank you!

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54260 488
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 55125 245
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44778 311
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

We're in Beta

About us Mission Statement