Как добавить строку в середине столбца в пандах

1

Я ищу решение, которое не включает функцию.apply или лямбда, которая проходит через список и объявляет строку по желаемому индексу. У меня есть столбец, похожий на это, с множеством записей:

df = pd.DataFrame(["1:77631829:-:1:77641672:-"], columns=["position"])

    position
0   1:77631829:-:1:77641672:-

Мне бы хотелось:

    position
0   chr1:77631829:-:chr1:77641672:-

Поэтому вставьте "chr" в начале и после третьего двоеточия :

Я бы подумал, что это будет так, но вставка не была реализована в серии:

"chr" + df["position"].str.split(":").insert(3, "chr").str.join(":")

Это делает это, но выглядит неэффективно:

"chr" + df["position"].str.split(":").str[:3].str.join(":") + "chr" + df["position"].str.split(":").str[3:].str.join(":")
  • 0
    Если вы абсолютно уверены в своем формате, тогда вы можете попробовать 'chr' + df['position'].str.replace('-:', '-:chr')
  • 0
    @RaunaqJain Опубликуйте это как решение, чтобы оно помогло другим, кто задает этот вопрос.
Показать ещё 1 комментарий
Теги:
pandas

1 ответ

1
Лучший ответ

Я думаю, вы можете использовать split на 3 значение : затем извлечь голову и хвост списков - соединить голову, добавить ch в хвост, добавить ch и последний добавить в список L:

df = pd.DataFrame(["1:77631829:-:1:77641672:-","1:77631829:-:1:77641672:-"], 
                  columns=["position"])
print (df)
                    position
0  1:77631829:-:1:77641672:-
1  1:77631829:-:1:77641672:-

L = []
for x in df["position"]:
    *i, j = x.split(':', 3)
    L.append(("chr" + ':'.join(i) + "chr" + j))

df['new'] = L
print (df)
                    position                             new
0  1:77631829:-:1:77641672:-  chr1:77631829:-chr1:77641672:-
1  1:77631829:-:1:77641672:-  chr1:77631829:-chr1:77641672:-

Решение Hack с комментариями:

'chr' + df['position'].str.replace('-:', '-:chr')

Быстрее со списком и f-строками:

df['new'] = [f"ch{x.replace('-:', '-:chr')}" for x in df['position']]

Производительность:

df = pd.DataFrame(["1:77631829:-:1:77641672:-","1:77631829:-:1:77641672:-"], 
                  columns=["position"])

#[20000 rows x 1 columns]
df = pd.concat([df] * 10000, ignore_index=True)

In [226]: %%timeit
     ...: L = []
     ...: for x in df["position"]:
     ...:     *i, j = x.split(':', 3)
     ...:     L.append(("chr" + ':'.join(i) + "chr" + j))
     ...: 
     ...: df['new1'] = L
     ...: 
18.9 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [227]: %%timeit
     ...: df['new2'] = "chr" + df["position"].str.split(":").str[:3].str.join(":") + "chr" + df["position"].str.split(":").str[3:].str.join(":")
     ...: 
50.8 ms ± 1.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [228]: %%timeit
     ...: df['new3'] = 'chr' + df['position'].str.replace('-:', '-:chr')
     ...: 
21.5 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [229]: %%timeit
     ...: df['new4'] = [f"ch{x.replace('-:', '-:chr')}" for x in df['position']]
     ...: 
8.59 ms ± 130 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
  • 2
    Просто крошечные придирки: OP не хочет использовать apply или lambda или петли. Если возможно, сравните ваше решение с 'chr' + df['position'].str.replace('-:', '-:chr') чтобы он получил идею, которая быстра и лучше.
  • 0
    @SandeepKadapa - Да, но циклы с текстовой функцией Python работают быстрее, чем функции без циклов pandas textx str .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню