Как получить столбец как Option<String> из поляра DataFrame?

Я пытаюсь получить Vec<Option<String>>, чтобы передать его в sqlx с нетронутыми нулевыми значениями. Основываясь на этом ТАК вопросе, я попробовал:

let names: Vec<Option<String>> = merged_df
    .column("description")?
    .str()?
    .into_iter()
    .map(|s| s.to_string())
    .collect();

Но это терпит неудачу с:

 1  error[E0599]: the method `to_string` exists for enum `Option<&str>`, but its trait bounds were not satisfied
     --> rust/load_all.rs:569:20
      |
 569  |         .map(|s| s.to_string())
      |                    ^^^^^^^^^ method cannot be called on `Option<&str>` due to unsatisfied trait bounds
      |
     ::: /Users/nick/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:570:1
      |
 570  | pub enum Option<T> {
      | ------------------ doesn't satisfy `_: TemporalMethods`, `std::option::Option<&str>: AsSeries`, `std::option::Option<&str>: ToString
 ` or `std::option::Option<&str>: std::fmt::Display`
      |
      = note: the following trait bounds were not satisfied:
              `std::option::Option<&str>: AsSeries`
              which is required by `std::option::Option<&str>: polars::prelude::TemporalMethods`
              `std::option::Option<&str>: std::fmt::Display`
              which is required by `std::option::Option<&str>: ToString`

Как я могу заставить это работать?

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
183
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам не хватает одного map(). Вам понадобится два: один для итератора, другой для Option:

let names: Vec<Option<String>> = merged_df
    .column("description")?
    .str()?
    .into_iter()
    .map(|s| s.map(|s| s.to_string()))
    .collect();

Примечание: вам следует предпочесть работу с собственными операциями Polars, а не такое преобразование. Это будет более эффективно.

Спасибо за ответ. Можете ли вы уточнить последний пункт? Я выполняю это преобразование только потому, что меня об этом просит компилятор; если я смогу избежать этого, даже лучше!

Nick K9 01.04.2024 14:19

@NickK9 Я не знаю, что вы пытаетесь сделать, поэтому не могу сказать, можно ли это сделать без преобразования; Я имею в виду только то, что если вы можете делать то, что хотите, без конвертации, используя API Polars, это лучше.

Chayim Friedman 01.04.2024 14:32

@NickK9 другими словами, что ты делаешь с names? Можете ли вы сделать это с помощью итераторов поляров, а не использовать итераторы поляров для копирования в vec и последующего выполнения реальных действий?

Dean MacGregor 02.04.2024 03:59

Ответ Хаима подойдет, если вам действительно нужно получить Vec<Option<String>> от Polars Series. Однако эта проблема с sqlx помогла мне понять, что это преобразование на самом деле не требуется при передаче строк с NULL-значением в sqlx. Вместо этого вы можете просто использовать приведение. В конце концов, вот код, который я использовал:

let names: Vec<Option<&str>> = merged_df
    .column("description")?
    .str()?
    .iter()
    .collect();

let _ = query!(
    "INSERT INTO district_resources (name)
        SELECT * FROM UNNEST (
            $1::text[]
        )",
    &names as &[Option<&str>]
)

Другие вопросы по теме