Столбец Polars из условного поиска значений словаря

Я хочу сопоставить ключ в одном фрейме данных Polars с другой базой Polars DF на основе отношений между столбцами. Это всего лишь пример, полные DF1 и DF2 намного больше (2,5 миллиона и 1,5 миллиона строк соответственно.

DF1 = = pl.DataFrame({
'chr' : ["GL000008.2", "GL000008.2", "GL000008.2", "GL000008.2","GL000008.2", "GL000008.2"], 
'start': [14516,17380,17381,20177,22254,24357], 
'end': [14534,17399,17399,20195,22274,24377]
})

DF2 = = pl.DataFrame({ 
'key' : [1,2,3,4,5,6],
'chrom' : ["GL000008.2", "GL000008.2", "GL000008.2", "GL000008.2","GL000008.2", "GL000008.2"], 
'start': [14516,15377,17376,20177,22254, 24357], 
'end': [14534,15403,17399,20195,22274,24377]})

Я хочу:

DF1 = = pl.DataFrame({
'chr' : ["GL000008.2", "GL000008.2", "GL000008.2", "GL000008.2","GL000008.2", "GL000008.2"], 
'start': [14516,17380,17381,20177,22254,24357], 
'end': [14534,17399,17399,20195,22274,24377],
'key': [1,3,3,4,5,6]
})

Я хотел бы назначить key из DF2 в DF1, когда chrom соответствует chr, а start и end в DF1 содержатся в begin и end в DF2.

Сначала я попытался выполнить итерацию по строкам DF1, найдя соответствующую запись в DF2:

sz = len(DF1[:,0])

for i in range(sz):
    DF1[i,"key"] = DF2.filter(
        (pl.col("chrom") == DF1[i,"chr"])\
        & (pl.col("begin") <= DF1[i,"start"])\
        & (pl.col("end") >= DF1[i,"end"])
        ).select('key')[0,0]

Итерация строк через DF невероятно медленная. Это занимает около 10 часов.

Я также пытался использовать np.array вместо непосредственно в df. это немного быстрее, но все еще очень медленно.

Я ищу способ сделать это, используя собственную структуру данных Polar. У меня нет ключа для присоединения, поэтому стратегии join и join_asof не работают.

Можете ли вы сделать свой пример воспроизводимым и показать ожидаемый результат, пожалуйста?

ignoring_gravity 15.02.2023 22:38

Поможет ли это? stackoverflow.com/a/73177515/20557510

ΩΠΟΚΕΚΡΥΜΜΕΝΟΣ 15.02.2023 22:47

Другой пример: github.com/pola-rs/polars/issues/5004#issuecomment-125978408‌​3

ΩΠΟΚΕΚΡΥΜΜΕΝΟΣ 15.02.2023 22:51

@ignoring_gravity Я попытался добавить объяснение получше, извините.

Jim Beck 16.02.2023 19:59

@ ΩΠΟΚΕΚΡΥΜΜΕΝΟΣ, спасибо за ваши предложения — но у меня нет ключа, чтобы присоединиться — на самом деле это всего три условия. На самом деле ключом является то, что я пытаюсь установить в DF1, чтобы я мог выполнять соединения.

Jim Beck 16.02.2023 19:59

Спасибо @JimBeck - это все еще не воспроизводимо. Вы можете опубликовать что-нибудь, что мы можем скопировать и вставить?

ignoring_gravity 16.02.2023 20:03

@ignoring_gravity Я добавил фактические полные DF1 и DF2 по ссылке на репозиторий, чтобы их можно было скачать. Приведенный выше код можно запустить в этих файлах. Я не уверен, что еще я могу предоставить, чтобы скопировать и вставить.

Jim Beck 16.02.2023 20:28

Что-то вроде df1 = pl.DataFrame({'start': [14516, 14517, ...], 'end': [14712, ...]}), df2 = ... . Мы должны иметь возможность запускать ваш код без загрузки данных

ignoring_gravity 16.02.2023 20:37

@ignoring_gravity Спасибо за руководство. И просто для ясности - код, который я написал, работает - он чертовски медленный.

Jim Beck 16.02.2023 21:02
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел &quot;Заголовок&quot; в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
0
9
121
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Join и filter должны дать вам то, что вам нужно:

(
    df1.join(df2, left_on = "chr", right_on = "chrom")
    .filter(
        (pl.col("start") >= pl.col("start_right"))
        & (pl.col("end") <= pl.col("end_right"))
    )
    .drop(["start_right", "end_right"])
)
shape: (6, 4)
┌────────────┬───────┬───────┬─────┐
│ chr        ┆ start ┆ end   ┆ key │
│ ---        ┆ ---   ┆ ---   ┆ --- │
│ str        ┆ i64   ┆ i64   ┆ i64 │
╞════════════╪═══════╪═══════╪═════╡
│ GL000008.2 ┆ 14516 ┆ 14534 ┆ 1   │
│ GL000008.2 ┆ 17380 ┆ 17399 ┆ 3   │
│ GL000008.2 ┆ 17381 ┆ 17399 ┆ 3   │
│ GL000008.2 ┆ 20177 ┆ 20195 ┆ 4   │
│ GL000008.2 ┆ 22254 ┆ 22274 ┆ 5   │
│ GL000008.2 ┆ 24357 ┆ 24377 ┆ 6   │
└────────────┴───────┴───────┴─────┘

Спасибо за решение. Я думал, что не могу использовать объединение, потому что поле chr представляет собой отношение «многие ко многим» между DF1 и DF2.

Jim Beck 18.02.2023 04:57

Использование join_asof может обеспечить эффективное решение:

(
    DF1
    .sort('start')
    .join_asof(
        DF2.sort('start'),
        by_left = "chr",
        by_right = "chrom",
        on = "start",
        strategy = "backward")
    .filter(
        pl.col('end') <= pl.col('end_right')
    )
)
shape: (6, 5)
┌────────────┬───────┬───────┬─────┬───────────┐
│ chr        ┆ start ┆ end   ┆ key ┆ end_right │
│ ---        ┆ ---   ┆ ---   ┆ --- ┆ ---       │
│ str        ┆ i64   ┆ i64   ┆ i64 ┆ i64       │
╞════════════╪═══════╪═══════╪═════╪═══════════╡
│ GL000008.2 ┆ 14516 ┆ 14534 ┆ 1   ┆ 14534     │
│ GL000008.2 ┆ 17380 ┆ 17399 ┆ 3   ┆ 17399     │
│ GL000008.2 ┆ 17381 ┆ 17399 ┆ 3   ┆ 17399     │
│ GL000008.2 ┆ 20177 ┆ 20195 ┆ 4   ┆ 20195     │
│ GL000008.2 ┆ 22254 ┆ 22274 ┆ 5   ┆ 22274     │
│ GL000008.2 ┆ 24357 ┆ 24377 ┆ 6   ┆ 24377     │
└────────────┴───────┴───────┴─────┴───────────┘

Примечание: это предполагает, что ваши начальные и конечные интервалы в DF2 не перекрываются.

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