regex 从字符串中提取多个信息以创建新列

kmbjn2e3  于 2023-06-30  发布在  其他
关注(0)|答案(3)|浏览(112)

我有以下 Dataframe

df = pd.DataFrame({'info':{0:'1cr1:782906:F:He:1:Ho1:0:Ho2:0',
                           1:'5cr1:782946:G:He:1:Ho1:0:Ho2:0'}})

看起来像这样

info
0   1cr1:782906:F:He:1:Ho1:0:Ho2:0
1   5cr1:782946:G:He:1:Ho1:0:Ho2:0

我想提取之间的第一和第二冒号的信息,第四和第五,第六和第七和第七冒号后的信息,并追加到新的列
结果应该如下所示。

info                               A       B    C   D
0   1cr1:782906:F:He:1:Ho1:0:Ho2:0    782906   1    0   0
1   5cr1:782946:G:He:1:Ho1:0:Ho2:0    782946   1    0   0

我相信下面应该给予我前三列,但我得到了一个预期的1D数组错误,我不确定如何在正则表达式中解释第四列

df['A','B','C'] = df['info'].str.extract(r'(:(\d*):)', expand=True)

https://regex101.com/r/83aj0l/1

0qx6xfy6

0qx6xfy61#

这里有一个方法:

df = (df.join(df['info']
              .str.extractall('(?<=:)(\d+)')
              .squeeze()
              .unstack()
              .rename(columns={k: v for k, v in enumerate([*'ABCD'])})
              )
      )

df

                             info       A  B  C  D
0  1cr1:782906:F:He:1:Ho1:0:Ho2:0  782906  1  0  0
1  5cr1:782946:G:He:1:Ho1:0:Ho2:0  782946  1  0  0
svujldwt

svujldwt2#

这应该可以工作,但是你必须一列一列地做,虽然这不是最干净的解决方案

df['A'] = df['info'].astype("str").apply(lambda x: [e for e in x.split(':') if e.isdigit()][0])
df['B'] = df['info'].astype("str").apply(lambda x: [e for e in x.split(':') if e.isdigit()][1])
h5qlskok

h5qlskok3#

一种可行的方法。首先,通过在:字符上拆分,将info列转换为值列表。

df["info"] = df["info"].apply(lambda x: x.split(":"))

完成后,可以使用.apply(pd.Series)创建一组列,每个列对应列表中的每个元素。每一行都被转换为pd.Series,这意味着输出是一个 Dataframe 。info_df = df['info'].apply(pd.Series)
如果info中的每个值总是具有相同数量的冒号分隔的子字符串,那么得到所需结果的简写是

df = pd.DataFrame({'info':{0:'1cr1:782906:F:He:1:Ho1:0:Ho2:0',
                           1:'5cr1:782946:G:He:1:Ho1:0:Ho2:0'}})

df[["A", "B", "C", "D", "E", "F", "G", "H", "I"]] = df["info"].apply(pd.Series)

相关问题