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

时间:2016-08-21 20:11:20

标签: python apply graphlab sframe

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

我的SFrame名为dog_distances(1000行x4列):

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通常会输出一个dict ... sframe_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值等于该行中的最小值,则返回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?

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

请试试这个:

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如果row [' dog-dog'] == min(row.values())else 0)

  3. Result

答案 2 :(得分:0)

我找到了解决方案:

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

实际上,传递给.apply()的变量/ object / text是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 :(得分:0)

我也遇到同样的问题。在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())