【问题标题】:Using regex to split a column使用正则表达式拆分列
【发布时间】:2021-04-23 06:54:20
【问题描述】:

我使用的正则表达式是\d+-\d+,但我不太确定如何分隔罗马数字以及如何使用它们创建新列。

我有这个数据集:

Date_Title                        Date                       Copies
05-21 I. Don Quixote              1605                       252
21-20 IV. Macbeth                 1629                       987
10-12 ML. To Kill a Mockingbird   1960                       478
12 V. Invisible Man               1897                       136

基本上,我想拆分“日期标题”,所以,当我打印一行时,我会得到:

('05-21 I', 'I', 'Don Quixote', 1605, 252)

或者

('10-12 ML', 'ML', 'To Kill a Mockingbird',1960, 478)

首先是数字和罗马数字,其次是;只有罗马数字,第三个是名称,第四个和第五个与数据集相同。

【问题讨论】:

  • 到目前为止你尝试过什么?你被困在哪里了?

标签: python regex pandas


【解决方案1】:

你可以使用

df = pd.DataFrame({'Date_Title':['05-21 I. Don Quixote','21-20 IV. Macbeth','10-12 ML. To Kill a Mockingbird','12 V. Invisible Man'], 'Date':[1605,1629,1960,1897], 'Copies':[252,987,478,136]})
rx = r'^(\d+(?:-\d+)?\s*(M{0,4}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})))\.\s*(.*)'
df[['NumRoman','Roman','Name']] = df.pop('Date_Title').str.extract(rx)
df = df[['NumRoman','Roman','Name', 'Date', 'Copies']]
>>> df
   NumRoman Roman                   Name  Date  Copies
0   05-21 I     I            Don Quixote  1605     252
1  21-20 IV    IV                Macbeth  1629     987
2  10-12 ML    ML  To Kill a Mockingbird  1960     478
3      12 V     V          Invisible Man  1897     136

请参阅regex demo详情

  • ^ - 字符串开头
  • (\d+(?:-\d+)?\s*(M{0,4}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3}))) - 第 1 组(“NumRoman”):
  • \. - 一个点
  • \s* - 零个或多个空格
  • (.*) - 第 3 组(“名称”):除换行符之外的任何零个或多个字符,尽可能多

注意df.pop('Date_Title') 删除Date_Title 列并将其作为extract 方法的输入。如果您需要保持原始列顺序,df = df[['NumRoman','Roman','Name', 'Date', 'Copies']] 是必需的。

【讨论】:

    【解决方案2】:

    我很确定可能会有更优化的解决方案,但这是解决问题的快速方法:

    df['Date_Title'] = df['Date_Title'].apply(lambda x: (x.split()[0],x.split()[1],' '.join(x.split()[2:])
    

    或者:

    df['Date_Title'] = (df['Date_Title'].str.split().str[0],
                        df['Date_Title'].str.split().str[1],
                        ' '.join(df['Date_Title'].str.split().str[2:])
    

    【讨论】:

      【解决方案3】:

      专注于字符串拆分:

      string = "21-20 IV. Macbeth"
      i = string.index(".")  # Finds the first point
      date, roman = string[:i].split() # 21-20, IV
      title = string[i+2:]  # Macbeth
      

      【讨论】:

        【解决方案4】:
        df=df.assign(x=df['Date_Title'].str.split('\.').str[0],y=df['Date_Title'].str.extract('(\w+(?=\.))'),z=df['Date_Title'].str.split('\.').str[1:].str.join(','))
        

        【讨论】:

          猜你喜欢
          • 2020-08-07
          • 2020-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多