优化python中的循环

时间:2016-09-09 16:31:59

标签: python pandas for-loop optimization

我有一个行走距离的数据框(df),我根据特定条件分配了一个标签。

distance=[0,0.0001,0.20,1.23,4.0]
df = pd.DataFrame(distance,columns=["distance"])
df['label']=0
for i in range(0, len(df['distance'])):   
      if (df['distance'].values[i])<=0.10:
          df['label'][i]=1
      elif (df['distance'].values[i])<=0.50:
          df['label'][i]=2
      elif (df['distance'].values[i])>0.50:
          df['label'][i]=3

这很好用。但是,我有超过100万个距离记录,这个for循环花费的时间比预期的要长。我们可以优化此代码以缩短执行时间吗?

3 个答案:

答案 0 :(得分:3)

通常,除非绝对必要,否则不应遍历DataFrame。使用已经优化的内置Pandas函数或使用矢量化方法,通常可以获得更好的性能。

在这种情况下,您可以使用locBoolean indexing进行分配:

# Initialize as 1 (eliminate need to check the first condition).
df['label'] = 1

# Case 1: Between 0.1 and 0.5
df.loc[(df['distance'] > 0.1) & (df['distance'] <= 0.5), 'label'] = 2

# Case 2: Greater than 0.5
df.loc[df['distance'] > 0.5, 'label'] = 3

另一种选择是使用pd.cut。这是一个方法对问题中的示例问题更专业。布尔索引是一种更通用的方法。

# Get the low and high bins.
low, high = df['distance'].min()-1, df['distance'].max()+1

# Perform the cut.  Add one since the labels start at zero by default.
df['label'] = pd.cut(df['distance'], bins=[low, 0.1, 0.5, high], labels=False) + 1

您也可以在上面的代码中使用labels=[1,2,3],而不是在结果中添加1。这会给df['labels']分类dtype而不是整数dtype。根据您的使用情况,这可能也可能不重要。

任一方法的结果输出:

   distance  label
0    0.0000      1
1    0.0001      1
2    0.2000      2
3    1.2300      3
4    4.0000      3

答案 1 :(得分:1)

通过为分档分配标签来使用cut

$(document).ready(function () {


    $.ajax({
                        url: "service.php",
                        data: data,
                        type: "POST",
                        success: function (response)
                        {
                            $.each(response.result, function (index, event) {
                                console.log(event.MaxCapacity)
                                $(".product-item[data-mydatavalue='" + event.EventName + "']").find('.maxCapacityForEvent').text(event.MaxCapacity);
                            });

                         $(".maxCapacityForEvent").each(function () {
                            if ($(this).html() === '')
                            {
                               $(this).html("Not Available");
                            }
                         });

                    }
                });
            });

答案 2 :(得分:0)

附带关于在切片副本上设置值的警告,但也许有人可以提出更清洁的选择?

只是基于花哨的索引来获取基于距离的子数组,然后写下你想要的值。

df.loc[:, "label"][df.loc[:, "distance"] <= 0.1] = 1
df.loc[:, "label"][(0.1 < df.loc[:, "distance"]) & (df.loc[:, "distance"] <= 0.5)] = 2
df.loc[:, "label"][df.loc[:, "distance"] > 0.5] = 3

编辑:新的和改进的,没有链式索引。