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

Posted

技术标签:

【中文标题】使用熊猫根据正则表达式分离列数据【英文标题】:Segregate a column data based on regex using pandas 【发布时间】:2021-07-09 10:34:56 【问题描述】:

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

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

我想创建 3 个新列

val_num - 将仅存储 NUMBER 值与符号一起出现,例如:1234(来自 >1234)和 1000(来自

val_str - 将只存储NUMBERsymbolsALPHABETS 的混合值,或者只是简单的字母,例如:31sadj。它可以有除&gt;,&lt;,=以外的任何符号

val_symbol - 将仅存储 3 个符号,例如 &gt;&lt;=

我尝试了以下但不准确

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-]+)') 

我希望我的输出如下所示

【问题讨论】:

那么什么不好呢?我看到df['val'].str.extract(r'([&lt;&gt;=]+)').fillna('=') 工作正常。 另外两个 clumns 正则表达式不能正常工作 【参考方案1】:

你可以使用

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 列填充有 ([^&lt;&gt;=]*[a-zA-Z][^&lt;&gt;=]*) 匹配项,用于搜索除 &lt;&gt;= 之外的零个或多个字符,然后是一个字母,然后是除 @ 之外的零个或多个字符987654331@、&gt;=

我得到的输出:

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

【讨论】:

【参考方案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

正则表达式详细信息

([&lt;&gt;=]+)? : 第一个捕获组匹配零次或一次

[&lt;&gt;=]+ :匹配列表中的一个或多个字符 [&lt;&gt;=]

((?&lt;=[&lt;&gt;=])\d+\.?\d*|\d+\.?\d*(?=$))? : : 第二个捕获组匹配零次或一次

(?&lt;=[&lt;&gt;=])\d+\.?\d* : 第一种选择 (?&lt;=[&lt;&gt;=])\d+\.?\d* :匹配列表中出现的符号之后的数字 [&lt;&gt;=] \d+\.?\d*(?=$) :第二个替代匹配行尾的数字

(.+)? : 第三个捕获组匹配匹配零次或一次

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

See the online regex demo

【讨论】:

以上是关于使用熊猫根据正则表达式分离列数据的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫数据框中使用正则表达式替换列值

熊猫使用正则表达式选择列并按值除

带有熊猫列的正则表达式

通过正则表达式将熊猫列替换为自身的一个子集

使用正则表达式根据列的值在数据集中创建新列

使用熊猫数据框的正则表达式