【问题标题】:Python DF issue. Match on the basis of column valuePython DF 问题。根据列值匹配
【发布时间】:2021-09-10 18:45:58
【问题描述】:

我有一个很大的 DF。如下图所示的 sn-p。

SrNo | Merchant | Revenue | Currency

1    | UBER SR  | 123     | INR

2    | UBER (SR)| 123     | INR

3    | SR UBER  | 123     | INR

4    | ZOMATO SR| 123     | INR

5    | ZOMATOSR | 123     | INR

6    |12FLIPAKRT| 123     | INR

7    | FLIPKART | 123     | INR

我的输出应该是这样的:

SrNo | Merchant | Revenue | Currency |Merchant_Flag

1    | UBER SR  | 123     | INR      | UBER

2    | UBER (SR)| 123     | INR      | UBER

3    | SR UBER  | 123     | INR      | UBER

4    | ZOMATO SR| 123     | INR      | ZOMATO

5    | ZOMATOSR | 123     | INR      | ZOMATO

6    |12FLIPAKRT| 123     | INR      | FLIPKART

7    | FLIPKART | 123     | INR      | FLIPKART

说明:我想在 Merchant 列中添加一个应具有值 wrt 的附加列,即如果 Merchant 列值中包含 UBER,则 Merchant_Flag 应为 UBER,对于其他 ZOMATO、FLIPKART 也是如此。

我的数据集很大。我尝试使用 re.search 然后 .replace 使用 if 和 else 来满足我的条件,这给了我性能问题。 我尝试过的另一个解决方案是使用 .loc

df.loc[df['columnname'].str.contains('')]。不知道如何进行。有人可以帮忙吗?

【问题讨论】:

  • 您在使用什么pysparkpandas,您认为应该如何处理拼写错误? i.e 12FLIPAKRT 不会被接走。

标签: python pandas pyspark string-matching .loc


【解决方案1】:

我会使用pandas.DataFrame.applymap 方法,在对对象执行迭代操作而不是编写普通的 for/while 循环时,在性能方面总是(根据经验)更好Python。这样您就可以避免多次调用pandas.DataFrame.loc 访问器的开销。

import re # import regex matching

df = pd.DataFrame({"Merchant":["UBER SR", "SR UBER", "ZOMATO SR", "12FLIPKART"]})

# Use applymap to quickly iterate over the whole dataframe
df["Merchant_Flag"] = df.applymap(lambda x: re.search(r"UBER|ZOMATO|FLIPKART", x).group(0))

(注意:.group(0)用于选择re.search的第一个匹配项)

输出:

     Merchant Merchant_Flag
0     UBER SR          UBER
1     SR UBER          UBER
2   ZOMATO SR        ZOMATO
3  12FLIPKART      FLIPKART

编辑

如果你不知道所有商家的名字,你需要稍微修改一下传递给applymap的函数:

import re # import regex matching

# Function definition
def match_merchant(elem, reg):
    # Match 
    m = re.search(reg, elem)
    if m != None:
        # Return first match if we got a match
        return m.group(0)
    else:
        # Here you may specify exactly what it is you want to return: None, empty String...
        return None 
    
df = pd.DataFrame({"Merchant":["UBER SR",
                               "SR UBER",
                               "ZOMATO SR",
                               "12FLIPKART",
                               "CABIFY"]})

# Merchants you want to match
regex = r"UBER|ZOMATO|FLIPKART"

# Use applymap to quickly iterate over the whole dataframe
df["Merchant_Flag"] = df.applymap(lambda x: match_merchant(x, regex))

输出:

     Merchant Merchant_Flag
0     UBER SR          UBER
1     SR UBER          UBER
2   ZOMATO SR        ZOMATO
3  12FLIPKART      FLIPKART
4      CABIFY          None

【讨论】:

  • 感谢您的信息。但是,它给了我一个错误,如下所述:- ----> AttributeError:'NoneType'对象没有属性'group'。你能指导我吗?
  • 当然,你能告诉我错误发生在哪里吗?是使用我的代码还是使用您的 DataFrame 时?也许我应该补充一点,鉴于您有多个列,您应该先选择列Merchant,然后再应用.applymap,如下所示:df["Merchant_Flag"] = df[["Merchant"]].applymap(lambda x: re.search(r"UBER|ZOMATO|FLIPKART", x).group(0))
  • 如果我按原样运行您的代码,它可以正常工作。但是当我在我的 DF 上使用它时,它给了我这个错误。
  • 如果我按原样运行您的代码,它可以正常工作。但是当我在我的 DF 上使用它时,它给了我这个错误。是的,我只在特定列上使用过。我正在使用以下代码 **df=pd.read_csv("myfile.csv") **和 df[["Merchant_Name"]].applymap(lambda x: re.search(r"UBER|ZOMATO|FLIPKART", x).group(0)) 。错误:pandas_libs\lib.pyx in pandas._libs.lib.map_infer() in (x)----> 1 df2["Merchant_Flag"] = df2[[" Merchant_Name"]].applymap(lambda x: re.search(r"UBER|ZOMATO|FLIPKART", x).group(0)) AttributeError: 'NoneType' object has no attribute 'group'
  • 这意味着re.search没有匹配到正则表达式中的任何商家。你还有其他商家吗?如果是这样,您应该将它们全部包含在r"UBER|ZOMATO|FLIPKART" 正则表达式中。如果您不知道传递给applymap 的函数的所有商家,则应修改以处理未匹配时的特殊情况,您的情况是这样吗?
【解决方案2】:

如果您知道可能存在哪些商家,那么您可以使用以下内容:

merchants = ['UBER', 'ZOMATO', 'FLIPKART']

for merchant in merchants:
    df.loc[df["Merchant"].str.contains(merchant), "Merchant_Flag"] = merchant

【讨论】:

  • @AnukritiSingh 很高兴它做到了。如果可以,请选择我的答案为正确的。这对我来说意义重大。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 2021-07-22
相关资源
最近更新 更多