【问题标题】:Compare two dataframe columns for matching percentage比较两个数据框列的匹配百分比
【发布时间】:2019-10-30 18:23:43
【问题描述】:

我想将一列的数据框与另一列的多列数据框进行比较,并返回具有最大匹配百分比的列的标题。

我在 pandas 中找不到任何匹配函数。第一个数据框第一列:

cars
----   
swift   
maruti   
wagonor  
hyundai  
jeep

第一个数据框第二列:

bikes
-----
RE
Ninja
Bajaj
pulsar

一列数据框:

words
---------
swift 
RE 
maruti
waganor
hyundai
jeep
bajaj

期望的输出:

100% match  header - cars

【问题讨论】:

    标签: python string pandas dataframe compare


    【解决方案1】:

    尝试使用 pandas DataFrame 的isin 函数。假设 df 是您的第一个数据框,而 words 是一个列表:

    In[1]: (df.isin(words).sum()/df.shape[0])*100
    Out[1]:
    cars     100.0
    bikes     20.0
    dtype: float64
    
    

    您可能需要将 df 和单词列表中的字符串小写以避免任何大小写问题。

    【讨论】:

    • 不错的一个班轮!但是,对我来说,它只有在 words 是一个列表时才有效。我认为当您将熊猫系列传递给isin 时,它会尝试匹配索引和值。因此,必须以相同的方式订购 Series 和 DataFrame 才能正常工作。
    【解决方案2】:

    您可以先将列放入列表中:

    dfCarsList = df['cars'].tolist()
    dfWordsList = df['words'].tolist()
    dfBikesList = df['Bikes'].tolist()
    

    然后迭代列表进行比较:

    numberCars = sum(any(m in L for m in dfCarsList) for L in dfWordsList)
    numberBikes = sum(any(m in L for m in dfBikesList) for L in dfWordsList)
    

    您可以使用的数字大于您的输出。

    【讨论】:

      【解决方案3】:

      使用numpy.in1dndarray.mean 构造一个Series,然后调用Series.idxmaxmax 方法:

      # Setup
      df1 = pd.DataFrame({'cars': {0: 'swift', 1: 'maruti', 2: 'waganor', 3: 'hyundai', 4: 'jeep'}, 'bikes': {0: 'RE', 1: 'Ninja', 2: 'Bajaj', 3: 'pulsar', 4: np.nan}})
      df2 = pd.DataFrame({'words': {0: 'swift', 1: 'RE', 2: 'maruti', 3: 'waganor', 4: 'hyundai', 5: 'jeep', 6: 'bajaj'}})
      
      match_rates = pd.Series({col: np.in1d(df1[col], df2['words']).mean() for col in df1})
      
      print('{:.0%} match header - {}'.format(match_rates.max(), match_rates.idxmax()))
      

      [出]

      100% match header - cars
      

      【讨论】:

        【解决方案4】:

        这是一个解决方案,其函数返回一个元组 (column_name, match_percentage) 用于具有最大匹配百分比的列。它接受 pandas 数据框(在您的示例中为自行车和汽车)和一系列(单词)作为参数。

        def match(df, se):
            max_matches = 0
            max_col = None
            for col in df.columns:
                # Get the number of matches in a column
                n_matches = sum([1 for row in df[col] if row in se.unique()])
                if n_matches > max_matches:
                    max_col = col
                    max_matches = n_matches
            return max_col, max_matches/df.shape[0]
        

        通过您的示例,您应该得到以下输出。

        df = pd.DataFrame()
        df['Cars'] = ['swift', 'maruti', 'wagonor', 'hyundai', 'jeep']
        df['Bikes'] = ['RE', 'Ninja', 'Bajaj', 'pulsar', '']
        se = pd.Series(['swift', 'RE', 'maruti', 'wagonor', 'hyundai', 'jeep', 'bajaj'])
        
        In [1]: match(df, se)
        Out[1]: ('Cars', 1.0)
        

        【讨论】:

          猜你喜欢
          • 2020-06-18
          • 1970-01-01
          • 2020-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多