【问题标题】:Using apply() method on SFrame issues在 SFrame 问题上使用 apply() 方法
【发布时间】:2016-08-21 20:11:19
【问题描述】:

背景:我有一个 SFrame,其中包含指示狗图像与其他图像的接近程度的数字。通常狗的图像应该最接近另一个狗的图像,但重点是测试评估方法

我的 SFrame 被称为 dog_distances(1000 行 x 4 列):

dog-automobile  dog-bird             dog-cat    dog-dog
41.9579761457   41.7538647304   36.4196077068   33.4773590373
46.0021331807   41.3382958925   38.8353268874   32.8458495684
42.9462290692   38.6157590853   36.9763410854   35.0397073189
41.6866060048   37.0892269954   34.5750072914   33.9010327697
39.2269664935   38.272288694    34.778824791    37.4849250909
40.5845117698   39.1462089236   35.1171578292   34.945165344

我想写一个函数来检查 dog-dog 是否是最小的数字,并将这个函数应用到整个 SFrame

访问 SFrame 的一行通常会输出一个字典... sframe_name[row#]['column_name']

将 .values() 添加到该行的末尾只会在列表中输出值。 这允许您应用诸如 min() 或 max() 之类的数学方法,这对于创建函数 is_dog_correct 很有用。

因此我的功能是:

def is_dog_correct(row):
    #checking if dog-dog is smallest value
    if dog_distances[row]['dog-dog'] == min(dog_distances[row].values()):
        return 1
    else:
        return 0

我的函数将 row 作为输入,如果该行的 dog-dog 值等于该行中的最小值,则返回 1。如果不正确,则返回 0。

运行 is_dog_correct(0) 输出 1。我们预计这是因为,正如您在上面看到的,第 0 行的 dog-dog 中的值是该行中的最小值。

运行 is_dog_correct(4) 输出 0。我们预计这是因为第 0 行的 dog-dog 中的值不是该行中的最小值。

所以函数 is_dog_correct 可以在一行一行的基础上完美运行!

当我按照建议在整个 sFrame 上运行时:dog_distances.apply(is_dog_correct)

我得到一个属性错误:

'SFrame' object has no attribute 'values'

请有人解释为什么该函数可以逐行运行,但不能在整个 SFrame 上运行??

【问题讨论】:

    标签: python apply graphlab sframe


    【解决方案1】:

    SFrame中的每一行都是一个python字典,其中键是列名,值是该列下的值。

    所以我认为你应该首先获取最小值的键,然后将其作为字符串进行比较。如果是狗返回1 否则返回0

    喜欢:

    if min(dog_distances[#row], key=dog_distances.get) == "dog-dog": ## the first part of the line will return the column name
        return 1
    else:
        return 0
    

    要使用apply(),您可以编写如下函数:

    def min_row(row):
        if min(row, key=row.get) == "dog-dog":
            return 1
        else:
            return 0
    

    要对您的数据使用此功能:

    my_result = dog_distances.apply(min_row)

    这将返回SArray

    【讨论】:

      【解决方案2】:

      我想出了解决办法:

      我认为问题在于所有文档都表明 .apply() 逐行进行。 我假设这意味着,当它在给定的行上运行一个函数时,传递的变量是作为整数的行号。

      其实传递给.apply()的变量/对象/文本是sframe_name[row_#]

      如果你想访问/操作给定的索引,那么在你的函数中

      sframe_name[row_#]['column_name']
      

      一般形式是这样的:

      passed_variable['column_name']
      

      为了完全透明,在我的函数中,确切的代码是:

      if dog-dog[row]['dog-bird'] <= dog-dog[row]['dog-dog']:
      

      代码应该是什么时候:

      if row['dog-bird'] <= row['dog-dog']:
      

      【讨论】:

        【解决方案3】:

        请试试这个:

        dog_distances['new_column'] = dog_distances.apply(lambda row: 1 if row['dog-dog'] == min(row.values()) else 0)
        

        添加

        嗨,史蒂文,

        此代码在我的笔记本电脑上正常工作。请看下面的链接。

        1. Your data(可能你的实际数据比这个长很多)

        2. 应用 Lambda

          dog_distances['new_column'] = dog_distances.apply(lambda row: 1 if row['dog-dog'] == min(row.values()) else 0)

        3. Result

        【讨论】:

        • 我尝试了你的建议,但得到了 KeyError: 'dog_dog'
        • 将列名从“dog_dog”更改为“dog-dog”。请重试。
        • 我试过了,这次我执行并创建了一个名为 new_column 的新列,但它用零填充。我对列求和只是为了看看某处是否有一个。总和为零。
        • 嗨史蒂文,我已经添加了结果。请看上面的链接。我想知道为什么这段代码在你这边不起作用。你能分享你的完整源代码吗?
        • 我今天早上从头开始重新编译了所有内容,这次你的 lambda 可以工作 :) 它昨天没有工作,因为我的代码中有“正确”列,其中包含 1 或 0。行的最小值始终是“正确”的列值
        【解决方案4】:

        我也遇到了同样的问题。当您在 SFrame 上使用 .apply() 时,它将 SFrame 的每一行作为字典传递。因此,在您的 is_dog_correct 函数中,将 row 视为字典。您可以使用 .values() 获取字典的值,然后找到它的最小值进行比较。如果 row['dog-dog'] 是最小值,您可以轻松返回 True 或 False:

        def is_dog_correct(row):
            return row['dog-dog'] == min(row.values())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-12
          • 2022-01-25
          • 1970-01-01
          • 2012-10-01
          • 2016-06-28
          • 2017-09-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多