基于多列的高效重复数据帧行选择'值

时间:2016-01-20 12:37:12

标签: python algorithm numpy pandas

这是我在pandas中的数据框的片段

         SubJob   DetectorName CategoryID DefectID  Image
0             0         NECK:1         79        5   
1             0         NECK:2         79        6   
2             0         NECK:3         92        4   
3             0         NECK:4         99      123   
4             0         NECK:5         99      124   
5             1         NECK:6         79       47   
6             1         NECK:7         91      631   
7             1         NECK:8         98      646   
8             1         NECK:9         99        7   
9             2         NECK:10        79       15   
10            2         NECK:11        89     1023   
11            2         NECK:12        79     1040   
12            2         NECK:13        79     2458   
13            3         NECK:14        73     2459   
14            3         NECK:15        87     2517   
15            3         NECK:15        79     3117   
16            3         NECK:16        79     3118   

直到n非常大

我们有多个subjobs whichare排序里面我们有多个categoryId被排序,在categoryId我们有多个defectId也被排序

我有一个单独的嵌套列表

[[CategoryId,DefectId,Image-Link] [CategoryId,DefectId,Image-Link] ...... m次] 米很大 这里是类别id,缺陷id表示整数值,图像链接是字符串

现在我反复从列表中选择categoryId,DefectId,并在数据框中找到与该categoryId,DefectId对应的行,并在该行中添加图像链接

我目前的代码是

for image_info_list in final_image_info_list:
    # add path of image in Image_Link 
    frame_main.ix[(frame_main["CategoryID"].values == image_info_list[0])
                                      & 
              (frame_main["DefectID"].values == image_info_list[1]), 
               "Image_Link"] = image_info_list[2]

这是完美的工作,但我的问题是因为n,m非常大,计算它是时候有很多其他适当的方法

我可以在这里应用二进制搜索吗?如果是,那么如何

1 个答案:

答案 0 :(得分:0)

对于固定的 n ,如果 m 足够大,您可以通过某些预处理更有效地执行查询。

(我将从下面的构思2开始,因为构思1 很多需要更多工作才能实现。)

创意1

首先,按Image-link对数据框进行排序。接下来,您可以在列的值上通过a bisect algorithms的三重应用找到任何三元组,每列一个。

您现在正在做的成本是 O(m n)。我建议的费用是 O(n log(n)+ m log(n))

这对于 m n 的某些值会更好,对其他值则更糟。例如,如果 m =Θ(n),那么您当前的算法是Θ(n 2 )=ω(n log(n)) 。 YMMV。

创意2

由于pandas是一个字符串序列,我猜测Image-link更难以搜索其中的特定值。您可以通过将字典映射到Dataframe中的索引列表来进行预处理。在极端情况下,每个Image-link值具有 O(1)行,这可以减少从Θ(mn)Θ的时间( n + m)

修改

在极端情况下,OP在评论中提到,所有dict([(k, i) for (i, k) in enumerate(df['Image-link'].values)]) 值都是唯一的。在这种情况下,可以构建一个字典,将它们的值映射到索引,如:

layer.selectAll("rect")
  .data(function(d) {
    return d;
  })
  .attr("x", function(d) {
    console.log("d = ", d) // this doesn't get called since there is no data
    return x(d.x);
  })