изменить строку в столбец с условиями в pandas - PullRequest
0 голосов
/ 01 мая 2020

У меня есть фрейм данных, такой как

Col1 Col2
G1 element.1:410022-411732(+):element_element
G1 element.2:678-10098(-):element_element
G1 element.4:6868-9899(-):element_element
G1 element.1:789-1222(+):element_element
G2 element.2:890-1220(-):element_element
G3 element.1:12-678(+):element_element
G3 element.1:1298-3000(-):element_element
G4 element.8:23222-98889(+):element_element
G5 element.1:1233-7789(-):element_element
G5 element.9:23333-23390(+):element_element

, поскольку вы можете видеть, что значение в Col2 имеет указанную c структуру:

содержимое элемента является переменным: element.9: 23333-23390 (+): element _ element

, но структура всегда одинакова: element.9 : 23333 - 23390 ( + ): element _ element

У вас всегда есть 2 числа, разделенных -: element.9: 23333-23390 (+): element_element

, и я хотел бы изменить значения в Col2, когда знак это = (-) путем вычитания из первого числа 1.

для примера element.1:1233-7789(-):element_element

становится

element.1:1232-7789(-):element_element

, потому что 1233-1 = 1232

здесь для всех примеров я должен получить новый df, такой как:

Col1 Col2
G1 element.1:410022-411732(+):element_element
G1 element.2:677-10098(-):element_element
G1 element.4:6867-9899(-):element_element
G1 element.1:789-1222(+):element_element
G2 element.2:889-1220(-):element_element
G3 element.1:12-678(+):element_element
G3 element.1:1297-3000(-):element_element
G4 element.8:23222-98889(+):element_element
G5 element.1:1232-7789(-):element_element
G5 element.9:23333-23390(+):element_element

Спасибо за вашу помощь

Я думаю, одна идея должна состоять в использовании str.split? Но я не знаю, как с этим справиться, поскольку здесь я должен split Col2 в 3 Col2bis column s:

Col1 Col2.1     Col2.2 Col2.3 
G1   element.9: 23333  -23390(+):element_element

, затем в Col2.2

df['Col2.2']=df['Col2.2']-1

и затем объединить 3 колонки еще раз

df["Col2"] = df["Col2.1"] + df["Col2.2"] + df["Col2.3"]

Ответы [ 4 ]

0 голосов
/ 01 мая 2020

Решение "pandasi c" с векторизованными операциями:

import pandas as pd
from io import StringIO

data = StringIO("""Col1,Col2
G1,element.1:410022-411732(+):element_element
G1,element.2:678-10098(-):element_element
G1,element.4:6868-9899(-):element_element
G1,element.1:789-1222(+):element_element
G2,element.2:890-1220(-):element_element
G3,element.1:12-678(+):element_element
G3,element.1:1298-3000(-):element_element
G4,element.8:23222-98889(+):element_element
G5,element.1:1233-7789(-):element_element
G5,element.9:23333-23390(+):element_element
""")

df = pd.read_csv(data, sep=',')

extracted = df["Col2"].str.extract(r"([^:]*:)(?P<num>\d+)([^(]*\()(?P<flag>[+-])(\).*)")

extracted["num"] = pd.to_numeric(extracted["num"])
extracted.loc[extracted["flag"] == "-", "num"] -= 1
extracted["num"] = extracted["num"].astype(str)

df["Col2"] = extracted[0].str.cat(extracted.iloc[:, 1:])
0 голосов
/ 01 мая 2020
import pandas as pd
from io import StringIO
import re

data = """
Col1 Col2
G1 element.1:410022-411732(+):element_element
G1 element.2:677-10098(-):element_element
G1 element.4:6867-9899(-):element_element
G1 element.1:789-1222(+):element_element
G2 element.2:889-1220(-):element_element
G3 element.1:12-678(+):element_element
G3 element.1:1297-3000(-):element_element
G4 element.8:23222-98889(+):element_element
G5 element.1:1232-7789(-):element_element
G5 element.9:23333-23390(+):element_element
"""

def replace_value(old):

    def sub(a, b):
        return int(a) - int(b)

    new = sub(*re.findall(r'[0-9]+', old)[:2][::-1])
    by_dot = old.split(':')
    return ':'.join([by_dot[0], '%d-%s' % (new, by_dot[1].split('-')[1]), by_dot[2]])

df = pd.read_csv(StringIO(data), sep='\s')

df.Col2 = df.Col2.map(replace_value)

print(df)

даст

  Col1                                        Col2
0   G1  element.1:410019-411732(+):element_element
1   G1     element.1:673-411732(+):element_element
2   G1    element.1:6861-411732(+):element_element
3   G1     element.1:786-411732(+):element_element
4   G2     element.1:885-411732(+):element_element
5   G3       element.1:9-411732(+):element_element
6   G3    element.1:1294-411732(+):element_element
7   G4   element.1:23212-411732(+):element_element
8   G5    element.1:1229-411732(+):element_element
9   G5   element.1:23322-411732(+):element_element
0 голосов
/ 01 мая 2020

Проверьте, работает ли это для вас: идея состоит в том, чтобы создать шаблон, выполнить вычитание и заменить строку методом pandas ' str.replace .

pat = r"(?P<start>.*\d:)(?P<num>\d+)(?P<end>.*\(-\))"
repl = lambda m: f'{m.group("start")}{int(m.group("num"))-1}{m.group("end")}'
df.Col2 = df.Col2.str.replace(pat,repl)
df

    Col1    Col2
0   G1  element.1:410022-411732(+):element_element
1   G1  element.2:677-10098(-):element_element
2   G1  element.4:6867-9899(-):element_element
3   G1  element.1:789-1222(+):element_element
4   G2  element.2:889-1220(-):element_element
5   G3  element.1:12-678(+):element_element
6   G3  element.1:1297-3000(-):element_element
7   G4  element.8:23222-98889(+):element_element
8   G5  element.1:1232-7789(-):element_element
9   G5  element.9:23333-23390(+):element_element
0 голосов
/ 01 мая 2020
import pandas as pd
from io import StringIO
import re

Поэтому я использую регулярное выражение для получения всех чисел из строки Col2, выбирая среднее значение, вычитая его и затем заменяя это значение обратно на столбец.

def func(x_):
    a = re.findall(r'\d+', x_)[1]
    return x_.replace(a, str(int(a)-1))

# Sample frame
x = StringIO("""Col1,Col2
G1,element.1:410022-411732(+):element_element
G1,element.2:678-10098(-):element_element
G1,element.4:6868-9899(-):element_element
G1,element.1:789-1222(+):element_element
G2,element.2:890-1220(-):element_element
G3,element.1:12-678(+):element_element
G3,element.1:1298-3000(-):element_element
G4,element.8:23222-98889(+):element_element
G5,element.1:1233-7789(-):element_element
G5,element.9:23333-23390(+):element_element
""")


df = pd.read_csv(x, sep=',')
df['Col2'] = df['Col2'].apply(lambda x: func(x))

print(df)

Выход:

  Col1                                        Col2
0   G1  element.1:410021-411732(+):element_element
1   G1      element.2:677-10098(-):element_element
2   G1      element.4:6867-9899(-):element_element
3   G1       element.1:788-1222(+):element_element
4   G2       element.2:889-1220(-):element_element
5   G3         element.1:11-678(+):element_element
6   G3      element.1:1297-3000(-):element_element
7   G4    element.8:23221-98889(+):element_element
8   G5      element.1:1232-7789(-):element_element
9   G5    element.9:23332-23390(+):element_element
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...