如何从数据框列的某些行中删除字符?

Posted

技术标签:

【中文标题】如何从数据框列的某些行中删除字符?【英文标题】:How to remove a character from some rows in a dataframe column? 【发布时间】:2021-06-16 22:27:20 【问题描述】:

我有一个大的 DataFrame 需要清理,作为示例,请查看此数据框:

import pandas as pd

cars = 'Brand': ['Honda Civic','Toyota Corolla','Ford Focus','Audi A4','Suzuki'],
        'Price': ['22000.T','25000.T','27000','.TPX','.NKM1']
        

df = pd.DataFrame(cars, columns = ['Brand', 'Price'])

print (df)

我想从单词的末尾删除'.T',并且只从包含的行的开头删除'.'

通过以下代码行,我可以删除'.T'

df['Price'].replace('.T', '', regex=True)

但它也从'.TPX' 中删除了'T'

对此的任何建议表示赞赏。

0    22000
1    25000
2    27000
3       PX
4    .NKM1
Name: Price, dtype: object

也用于在我添加此行时删除 '.'

f['Price'].replace('.', '', regex=True)

我得到了一个与我预期不同的数据框

0    
1    
2    
3    
4    
Name: Price, dtype: object

【问题讨论】:

【参考方案1】:

另一种方法是使用 numpy.where 并使用 str.startswithstr.endswith 评估您的条件:

import numpy as np

p = df['Price'].str
df['Price'] = np.where(p.startswith('.'),p.replace('.','',regex=True),
                         np.where(p.endswith('.T'),p.replace('.T','',regex=True),p))

这将检查df['Price'] 是以. 开头还是以.T 结尾并替换它们。

            Brand  Price
0     Honda Civic  22000
1  Toyota Corolla  25000
2      Ford Focus  27000
3         Audi A4    TPX
4          Suzuki   NKM1

【讨论】:

【参考方案2】:

Series.str.replace

df['Price'] = df['Price'].str.replace(r'^(?:\.)?(.*?)(?:\.T)?$', r'\g<1>')

Series.str.extract

df['Price'] = df['Price'].str.extract(r'^(?:\.)?(.*?)(?:\.T)?$', expand=False)

            Brand  Price
0     Honda Civic  22000
1  Toyota Corolla  25000
2      Ford Focus  27000
3         Audi A4    TPX
4          Suzuki   NKM1

正则表达式详细信息:

^ : 在行首断言位置 (?:\.) :匹配字符 . 的非捕获组 ? :匹配前一个非捕获组零次或一次 (.*?) :捕获匹配除行终止符之外的任何字符零次或多次但尽可能少的组 (lazy match) (?:\.T) :匹配 .T 的非捕获组 ? :匹配前一个非捕获组零次或一次 $ : 在行尾断言位置

Regex demo

【讨论】:

@anky 因为它还会在开头和结尾删除不需要的字符..考虑假想词ABCDDTTT.T 所以使用.rstrip(.T) 会导致ABCDD 这意味着它也会删除额外的@最后是 987654341@,这可能是不受欢迎的......虽然如果这不是数据集中的问题,那么我们绝对可以使用 rstrip.【参考方案3】:

您应该能够通过锚点和所谓的积极后视来实现您想要的。

df['Price'].replace('(?&lt;=.)\.T$', '', regex=True)

对于正则表达式,有一些特殊字符增加了功能。在这里,'$' 表示以结尾。因此,如果您只想影响以“.T”结尾的刺痛,则需要将其添加到末尾。后面的表达式部分是'(?

我真的不知道如何解释它,除了它有点类似于 CSS 类的工作方式,这真的不是一个很好的例子。

'?

替换以'.'开头的单词很简单。就是对面的锚,

df['Price'].replace('^\.', '', regex=True)

https://regex101.com/ 是一个很棒的网站,可以帮助您构建正则表达式。它还将解释您的正则表达式的作用。

【讨论】:

【参考方案4】:

你也可以使用numpy.select:

In [178]: import numpy as np

In [179]: conds = [df.Price.str.endswith('.T'), df.Price.str.startswith('.')]
In [182]: choices = [df.Price.str.replace('.T', '', regex=True), df.Price.str.replace('.', '', regex=True)]

In [189]: df.Price = np.select(conds, choices, default=df.Price)

In [190]: df
Out[190]: 
            Brand  Price
0     Honda Civic  22000
1  Toyota Corolla  25000
2      Ford Focus  27000
3         Audi A4    TPX
4          Suzuki   NKM1

【讨论】:

【参考方案5】:

您可以匹配字符串开头的点,也可以匹配结尾的.T。然后在替换中使用一个空字符串。

\A\.|\.T\Z

例如

import pandas as pd

cars = 'Brand': ['Honda Civic','Toyota Corolla','Ford Focus','Audi A4','Suzuki'],
        'Price': ['22000.T','25000.T','27000','.TPX','.NKM1']
        

df = pd.DataFrame(cars, columns = ['Brand', 'Price'])
df['Price'] = df['Price'].replace(r"\A\.|\.T\Z", "", regex=True)
print(df)

输出

            Brand  Price
0     Honda Civic  22000
1  Toyota Corolla  25000
2      Ford Focus  27000
3         Audi A4    TPX
4          Suzuki   NKM1

【讨论】:

【参考方案6】:

我想解释一下为什么你会得到这个结果。这是因为.在模式中使用时具有特殊含义,re docs特殊字符列表以

开头

.(点)在默认模式下,它匹配除 a 之外的任何字符 新队。如果已指定 DOTALL 标志,则匹配任何 包括换行符的字符。

所以当你的意思是 literal . 你需要转义它,考虑下面的例子

df = pd.DataFrame("col1":["3.45"])
df["unescaped"] = df.col1.replace(r'.','X',regex=True)
df["escaped"] = df.col1.replace(r'\.','X',regex=True)
print(df)

输出

   col1 unescaped escaped
0  3.45      XXXX    3X45

请注意,我在这里使用了所谓的原始字符串,它允许在模式中以更易读的形式转义具有特殊含义的字符(如果没有原始字符串,我将不得不写 '\\.',请参阅 re 文档以获取更多信息) .如果您对正则表达式模式感到困惑,我建议您使用regex101.com 来获得它的解释。

【讨论】:

【参考方案7】:

使用

>>> df['Price'].str.replace(r'^\.|\.T$', '', regex=True)
0    22000
1    25000
2    27000
3      TPX
4     NKM1

见regex proof。

解释

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  \.                       '.'
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  \.                       '.'
--------------------------------------------------------------------------------
  T                        'T'
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

【讨论】:

以上是关于如何从数据框列的某些行中删除字符?的主要内容,如果未能解决你的问题,请参考以下文章

根据底行中的值对数据框列的顺序进行排序

如何删除文件中某些行中的特定字符?

如何使用模块 re 从数据框列中删除特殊字符? [复制]

如何从 Python 的数据框列中的字符串中删除非字母数字字符?

如何从 pyspark 数据框列中的列表中删除特定字符串

如何从连接的数据框列中替换 NaN?