【问题标题】:Pandas - get row and column name for each element during applymapPandas - 在应用映射期间检索每个元素的行名和列名
【发布时间】:2017-09-25 01:38:36
【问题描述】:

我正在尝试比较 2 个字符串列表的相似性,并将它们呈现在 pandas 数据框中以供检查;所以我使用 1 个列表作为索引,另一个作为列列表。然后我想计算它们的“Levenshtein 相似度”(一个比较两个词之间相似度的函数)。

我试图通过使用应用映射来实现这一点,它将进入每个单元格,并将单元格索引与单元格列进行比较。但我怎么能这样做呢?或者也许会有一些更简单的方法?

things = ['car', 'bike', 'sidewalk', 'eatery']
action = ['walking', 'caring', 'biking', 'eating']
matrix = pd.DataFrame(index = things, columns = action)

def lev(x):
    x = Levenshtein.distance(x.index, x.column)  
matrix.applymap(lev)

到目前为止,我使用了以下(下),但我发现它笨拙且缓慢

matrix = pd.DataFrame(data = [action for i in things], index = things, columns = action)
for i, values in matrix.iterrows():
    for j, value in enumerate(values):
        matrix.ix[i,j] = Levenshtein.distance(i, value) 

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我认为您可以使用apply,对于列值使用.name

    def lev(x):
        #replace your function
        return x.index + x.name
    a = matrix.apply(lev)
    print (a)
                      walking          caring          biking          eating
    car            carwalking       carcaring       carbiking       careating
    bike          bikewalking      bikecaring      bikebiking      bikeeating
    sidewalk  sidewalkwalking  sidewalkcaring  sidewalkbiking  sidewalkeating
    eatery      eaterywalking    eaterycaring    eaterybiking    eateryeating
    

    编辑:

    如果需要一些算术运算,请使用broadcasting:

    a = pd.DataFrame(matrix.index.values + matrix.columns.values[:,None], 
                     index=matrix.index, 
                     columns=matrix.columns)
    print (a)
                 walking       caring           biking         eating
    car       carwalking  bikewalking  sidewalkwalking  eaterywalking
    bike       carcaring   bikecaring   sidewalkcaring   eaterycaring
    sidewalk   carbiking   bikebiking   sidewalkbiking   eaterybiking
    eatery     careating   bikeeating   sidewalkeating   eateryeating
    

    或者:

    a = pd.DataFrame(matrix.index.values + matrix.columns.values[:, np.newaxis], 
                     index=matrix.index, 
                     columns=matrix.columns)
    print (a)
                 walking       caring           biking         eating
    car       carwalking  bikewalking  sidewalkwalking  eaterywalking
    bike       carcaring   bikecaring   sidewalkcaring   eaterycaring
    sidewalk   carbiking   bikebiking   sidewalkbiking   eaterybiking
    eatery     careating   bikeeating   sidewalkeating   eateryeating
    

    【讨论】:

    • 太棒了——谢谢。但是没有办法通过矢量化/元素操作来实现吗?你所做的基本上就是我一直在用 iterrows 做的事情
    • 这取决于你需要什么。如果只需要一些算术运算,请使用 numpy。
    • 我明白了,但我不是在算术运算之后,而是像问题中那样对每个单元格应用一个简单的函数。我认为 applymap,作为一个元素方法就可以了。
    • 是的,但是与applymap 中的索引和列值没有任何联系 - 请通过a.applymap(lambda x: print (x)) 检查它
    • 好的,所以我知道无论如何我都必须使用 apply / iterrows 进行迭代。有点失望,但是谢谢
    【解决方案2】:

    您可以通过“嵌套apply”来做到这一点,如下所示:

    things = ['car', 'bike', 'sidewalk', 'eatery']
    action = ['walking', 'caring', 'biking', 'eating']
    matrix = pd.DataFrame(index=things, columns=action)
    matrix.apply(lambda x: pd.DataFrame(x).apply(lambda y: LD(x.name, y.name), axis=1))
    

    输出:

              walking  caring  biking  eating
    car             6       3       6       5
    bike            6       5       3       5
    sidewalk        7       8       7       8
    eatery          6       5       6       3
    

    这里调用pd.DataFrame(x)是因为x是一个Series对象,而Series.apply类似于applymap,不携带indexcolumns信息。

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 1970-01-01
      • 2018-09-29
      • 2020-12-12
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2019-12-04
      相关资源
      最近更新 更多