【问题标题】:Applying function to every cell in a Dataframe based on index and col基于 index 和 col 将函数应用于 Dataframe 中的每个单元格
【发布时间】:2018-11-27 19:00:39
【问题描述】:

我有一个熊猫数据框,其格式与this question 中的格式完全相同,我正在尝试实现相同的结果。就我而言,我正在计算行索引与其对应的列之间的fuzz-ratio

如果我尝试此代码(基于链接问题的答案)

def get_similarities(x):
    return x.index + x.name

test_df = test_df.apply(get_similarities)

行索引和列名的连接是按单元格进行的,正如预期的那样。正如预期的那样,运行 type(test_df) 返回 pandas.core.frame.DataFrame

但是,如果我像这样使代码适应我的场景

def get_similarities(x):
    return fuzz.partial_ratio(x.index, x.name)

test_df = test_df.apply(get_similarities)

它不起作用。我返回的是一个系列,而不是数据框(该函数的返回类型是 int

我不明白为什么这两个样本的行为不同,也不明白如何修复我的代码,使其返回一个数据框,每个单元格的 fuzzy.ratio 位于该单元格的行索引和列名之间那个细胞。

【问题讨论】:

    标签: python pandas dataframe fuzzywuzzy


    【解决方案1】:

    有一种方法可以通过DataFrame.apply 进行一些行操作。

    假设'test_df`如下:

    In [73]: test_df
    Out[73]: 
                      walking          caring          biking          eating
    car            carwalking       carcaring       carbiking       careating
    bike          bikewalking      bikecaring      bikebiking      bikeeating
    sidewalk  sidewalkwalking  sidewalkcaring  sidewalkbiking  sidewalkeating
    eatery      eaterywalking    eaterycaring    eaterybiking    eateryeating
    
    In [74]: def get_ratio(row):
        ...:     return row.index.to_series().apply(lambda x: fuzz.partial_ratio(x, 
        ...: row.name))
        ...: 
    
    In [75]: test_df.apply(get_ratio)
    Out[75]: 
              walking  caring  biking  eating
    car            33     100       0      33
    bike           25      25      75      25
    sidewalk       73      20      22      36
    eatery         17      33       0      50
    

    【讨论】:

      【解决方案2】:

      花了一些时间挖掘,但我想通了。问题在于DataFrame.apply 是按列或按行应用的,而不是逐个单元格的。因此,您的 get_similarities 函数实际上是一次访问整行或整列数据!默认情况下,它会获取整列——因此,要解决您的问题,您只需创建一个 get_similarities 函数,该函数返回一个列表,您可以在其中手动调用每个元素上的 fuzz.partial_ratio,如下所示:

      import pandas as pd 
      from fuzzywuzzy import fuzz
      
      def get_similarities(x):
      
          l = []
          for rname in x.index:
              print "Getting ratio for %s and %s" % (rname, x.name)
              score = fuzz.partial_ratio(rname,x.name)
              print "Score %s" % score
              l.append(score)
      
          print len(l)
          print
          return l
      
      
      
      a = pd.DataFrame([[1,2],[3,4]],index=['apple','banana'], columns=['aple','banada'])
      c = a.apply(get_similarities,axis=0)
      
      print c
      print type(c)
      

      我将我的打印语句留在了他们的文件中,这样您就可以看到 DataFrame.apply 调用为您自己做了什么——这就是我点击它的时候。

      【讨论】:

        【解决方案3】:

        下面的方法呢?

        假设我们有两组字符串:

        In [245]: set1
        Out[245]: ['car', 'bike', 'sidewalk', 'eatery']
        
        In [246]: set2
        Out[246]: ['walking', 'caring', 'biking', 'eating']
        

        解决方案:

        In [247]: from itertools import product
        
        In [248]: res = np.array([fuzz.partial_ratio(*tup) for tup in product(set1, set2)])
        
        In [249]: res = pd.DataFrame(res.reshape(len(set1), -1), index=set1, columns=set2)
        
        In [250]: res
        Out[250]:
                  walking  caring  biking  eating
        car            33     100       0      33
        bike           25      25      75      25
        sidewalk       73      20      22      36
        eatery         17      33       0      50
        

        【讨论】:

        • 为了脑筋急转弯,这怎么能通过pd.DataFrame.apply完成?
        • @iDrwish,如果fuzz.partial_ratio 能够使用向量而不是字符串,那将非常容易......我不知道如何使用.apply() 来克服这个限制。 .
        猜你喜欢
        • 2017-01-21
        • 2017-12-09
        • 1970-01-01
        • 2015-09-13
        • 2019-06-26
        • 2017-04-02
        • 1970-01-01
        • 2020-08-11
        • 2020-10-13
        相关资源
        最近更新 更多