在 SFrame 问题上使用 apply() 方法

Using apply() method on SFrame issues

背景: 我有一个 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[行#]['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

我的函数将行作为输入,如果该行的 dog-dog 值等于该行中的最小值,则 returns 1。如果这不是真的,它 returns 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 上工作?

请试试这个:

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

添加

嗨史蒂文,

这段代码在我的笔记本电脑上运行正常。请参阅下面的link。

  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

我找到了解决方案:

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

其实传给.apply()的variable/object/text是sframe_name[row_#]

所以在你的函数中,如果你想 access/act 在给定的索引上

sframe_name[row_#]['column_name']

通用形式是这样的:

passed_variable['column_name']

为了完全 运行sparent,在我的函数中,确切的代码是:

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

当代码应该是:

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

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

所以我觉得你应该先获取最小值的键,然后将它作为一个字符串进行比较。如果是狗 return 1 else return 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)

哪个会 return SArray

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

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