Я ищу решение, которое не включает функцию.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(":")
Я думаю, вы можете использовать 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)
apply
или lambda
или петли. Если возможно, сравните ваше решение с 'chr' + df['position'].str.replace('-:', '-:chr')
чтобы он получил идею, которая быстра и лучше.
str
.
'chr' + df['position'].str.replace('-:', '-:chr')