用熊猫的条件将字符串更改为列

时间:2020-05-01 09:05:38

标签: python regex pandas

我有一个数据框,例如

FractionallySizedBox(
  widthFactor: 0.98,
  heightFactor: 0.98,
  child: YourChild(),
),

如您所见,Col2中的值具有特定的结构:

元素内容是变量: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 :23333-23390(+):element.9 _ element

但结构始终相同:element.9 element 23333 : 23390 - + ( element ): element

您总是有两个数字,它们之间用_隔开:element.9:-(+):element_element

我想在符号= {23333-23390时通过从第一个数字中减去1来更改Col2中的值。

例如(-)

成为

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

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

在所有示例中,我应该得到一个新的df,例如:

1233-1 = 1232

感谢您的帮助

我猜一个想法应该是使用str.split吗?但是我不知道如何处理它,因为在这里我必须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 进入split Col2 s:

3 Col2bis column

然后转到Col2.2

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

然后再次融合3列

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

3 个答案:

答案 0 :(得分:0)

带有矢量化操作的“熊猫式”解决方案:

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

答案 1 :(得分:-1)

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

答案 2 :(得分:-1)

检查是否对您有用:这个想法是创建一个模式,进行减法,然后用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