将字符串更改为包含条件的列

2024-06-16 12:01:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧,比如

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中的值具有特定的结构:

元素内容是可变的:element.9:23333-23390(+):element{}

但是结构总是一样的:element.9:23333-23390(+):element_element

您总是有两个数字由-:element分隔。9:23333-23390(+):element\u element

当符号为=(-)时,我想通过从第一个数字1中减去来更改Col2中的值

例如element.1:1233-7789(-):element_element

变成

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

因为1233-1 = 1232

对于all示例,我应该获得一个新的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 columns:

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"]

Tags: 数据元素内容df数字element结构col2
3条回答
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

检查这是否对您有效:其想法是创建一个模式,进行减法运算,并用pandasstr.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

具有矢量化操作的“泛ASIC”解决方案:

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:])

相关问题 更多 >