使用熊猫基于正则表达式分离列数据

时间:2021-04-14 11:17:41

标签: python regex pandas string dataframe

我有一个如下所示的数据框

df = pd.DataFrame({'val': ['>1234','<>','<1000','<test','31sadj',123,43.21]})

我想创建 3 个新列

val_num - 将仅存储与符号一起出现的 NUMBER 值,例如:1234(来自 >1234)和 1000(来自 <1000)但不会存储 31(来自 31sadj),因为它没有任何符号

val_str - 将仅存储 NUMBERsymbolsALPHABETS 或纯字母组合的值,例如:31sadj。它可以有除 ><=

之外的任何符号

val_symbol - 将仅存储 3 个符号,例如 ><=

我尝试了以下但不准确

df['val_SYMBOL'] = df['val'].str.extract(r'([<>=]+)').fillna('=')
df['val_num'] = df['val'].str.extract(r'([0-9]+)')
df['val_str'] = df['val'].str.extract(r'([a-zA-Z0-9\s-]+)') 

我希望我的输出如下所示

enter image description here

2 个答案:

答案 0 :(得分:2)

你可以使用

df['val_SYMBOL'] = df['val'].astype(str).str.extract(r'([<>=]+)').fillna('=')
df['val_num'] = df['val'].astype(str).str.extract(r'\b(\d+(?:\.\d+)?)\b')
df['val_str'] = df['val'].astype(str).str.extract(r'([^<>=]*[a-zA-Z][^<>=]*)')

您要处理混合数据类型的列,因此第一个操作是使用 astype(str) 将数据转换为字符串。

val_num 列填充了 \b(\d+(?:\.\d+)?)\b 匹配项、作为整个单词匹配的整数或浮点数(\b 代表单词边界)。

val_str 列填充有 ([^<>=]*[a-zA-Z][^<>=]*) 匹配项,搜索除 <>= 之外的零个或多个字符,然后是一个字母然后又是零个或多个字符,除了 <>=

我得到的输出:

>>> df
      val val_SYMBOL val_num val_str
0   >1234          >    1234     NaN
1      <>         <>     NaN     NaN
2   <1000          <    1000     NaN
3   <test          <     NaN    test
4  31sadj          =     NaN  31sadj
5     123          =     123     NaN
6   43.21          =   43.21     NaN

答案 1 :(得分:2)

Series.str.extract

我们可以将 extract 与包含三个捕获组的正则表达式模式结合使用。

df['val'].astype(str).str.extract(
    r'([<>=]+)?((?<=[<>=])\d+\.?\d*|\d+\.?\d*(?=$))?(.+)?').fillna({0: '='})

    0      1       2
0   >   1234     NaN
1  <>    NaN     NaN
2   <   1000     NaN
3   <    NaN    test
4   =    NaN  31sadj
5   =    123     NaN
6   =  43.21     NaN

正则表达式详情

  • ([<>=]+)? :第一个捕获组匹配零次或一次

    • [<>=]+ :匹配列表中的一个或多个字符 [<>=]
  • ((?<=[<>=])\d+\.?\d*|\d+\.?\d*(?=$))? :: 第二个捕获组匹配零次或一次

    • (?<=[<>=])\d+\.?\d* :第一个选择
      • (?<=[<>=])\d+\.?\d* :匹配列表中出现的符号 [<>=]
      • 之后的数字
    • \d+\.?\d*(?=$) : 第二个选项匹配行尾的数字
  • (.+)? : 第三个捕获组匹配匹配零次或一次

    • .+ :匹配任意字符一次或多次。

See the online regex demo