【问题标题】:Match data between 2 pandas data frame and extract the matching value of another column in Python匹配2个熊猫数据框之间的数据并在Python中提取另一列的匹配值
【发布时间】:2018-10-01 17:15:30
【问题描述】:

我有两个熊猫数据框。

df1 :
     ACNo       Product
1   12340       100% Hot Care
2   23867       Auction5
3   98372       Edition
4   09837       Diet Parameter
5   54332       Load

df2 :
    ProdDetail                          AttrName
1   12345.567                           Age Confirmation
2   Model1 Count\100% Hot Care          Recipe
3   123445\Handle                       Improve
4   Diet Edition\Parameter              Amount

我想在 df2 的 ProdDetail 列上查找来自 df1 的 Product 列,并在 df1 中添加 AttrName 列以及相应的值。字符串可以在 ProdDetails 中的任意位置,基本类似于 excel 中的通配符功能。如果字符串出现在 df2 的 ProdDetail 中,我想提取相应的 AttrName。结果 df1 数据框应如下所示

        ACNo        Product             AttrName
1       12340       100% Hot Care       Recipe  
2       23867       Auction5            N/A
3       98372       Edition             Amount
4       09837       Diet Parameter      N/A
5       54332       Load                N/A

有人可以帮我解决这个问题吗?我尝试了多种方法,但无法找到解决方案。我看到了一个类似的帖子,但它是在 R 中,在 Python 中找不到。以下是我尝试过的一种方式

ip=df1['Product']
def lookup_prod(ip):
      return df2[(df2['ProdDetail'].str.contains(ip, na=False))]['AttrName']
df1['AttrName'] = data.apply(lambda row: lookup_prod(row['ProdDetails']), axis=1)

df1 = pd.DataFrame({'ACNo': ['12340', '23867', '98372', '09837', '54332'],
                    'Product': ['100% Hot Care', 'Auction5', 'Edition', 'Diet Parameter', 'Load']})

df2 = pd.DataFrame({'ProdDetail': [12345.567, r'Model1 Count\100% Hot Care',
                                   r'123445\Handle',  r'Diet Edition\Parameter'],
                    'AttrName': ['Age Confirmation', 'Recipe' , 'Improve',  'Amount']})

【问题讨论】:

    标签: python string pandas dataframe


    【解决方案1】:

    一种方法是将pd.Series.apply 与自定义函数和for 循环一起使用:

    def lookup_prod(ip):
        for row in df2.itertuples():
            if ip in row[1]:
                return row[2]
        else:
            return 'N/A'
    
    df1['AttrName'] = df1['Product'].apply(lookup_prod)
    
    print(df1)
    
    #     ACNo        Product AttrName
    # 1  12340        HotCare   Recipe
    # 2  23867        Auction      N/A
    # 3  98372        Edition   Amount
    # 4   9837  DietParameter      N/A
    # 5  54332           Load      N/A
    

    示例 #2

    此方法仍然有效:

    import pandas as pd
    
    df1 = pd.DataFrame({'ACNo': ['12340', '23867', '98372', '09837', '54332'],
                        'Product': ['100% Hot Care', 'Auction5', 'Edition', 'Diet Parameter', 'Load']})
    
    df2 = pd.DataFrame({'ProdDetail': [r'Sesonal Items\Limted  Number', r'Model1 Count\100% Hot Care',
                                       r'123445\Handle',  r'Diet Edition\Parameter'],
                        'AttrName': ['Age Confirmation', 'Recipe' , 'Improve',  'Amount']})
    
    def lookup_prod(ip):
        for row in df2.itertuples():
            if ip in str(row.ProdDetail):
                return row.AttrName
        else:
            return 'N/A'
    
    df1['AttrName'] = df1['Product'].apply(lookup_prod)
    
    print(df1)
    
    #     ACNo         Product AttrName
    # 0  12340   100% Hot Care   Recipe
    # 1  23867        Auction5      N/A
    # 2  98372         Edition   Amount
    # 3  09837  Diet Parameter      N/A
    # 4  54332            Load      N/A
    

    【讨论】:

    • 感谢 jpp,当我在整个数据集上运行时出现错误。 “TypeError:'float' 类型的参数不可迭代”。可能是因为“in”。
    • @amark,此解决方案适用于您提供的数据。所以看起来你有非字符串数据。您应该检查是否是这种情况,并 edit 您的问题是否与示例数据一起重要。
    • 是的,我看到了某些行包含非字符串数据的实例。我更改了标题和示例数据。
    • @amark,查看更新。该方法仍然有效。请给minimal reproducible example,按照我的回答方式,否则无法确认您的数据有什么问题。
    • 我为混乱道歉,我对此很陌生。我在上面的问题中更改了 df2 的数据样本。试图复制浮动错误。
    【解决方案2】:

    我认为str.contains 仍然在这里工作

    df1.Product.apply(lambda x : df2.AttrName[df2.ProdDetail.str.contains(x)].sum(),1)
    Out[805]: 
    1    Recipe
    2     False
    3    Amount
    4     False
    5     False
    Name: Product, dtype: object
    

    【讨论】:

      猜你喜欢
      • 2019-01-20
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2021-05-15
      相关资源
      最近更新 更多