【问题标题】:Points within buffer with the same id缓冲区内具有相同 id 的点
【发布时间】:2021-09-29 04:09:41
【问题描述】:

我有一个缓冲层和一个点层:

 buffer_gdf
     ID
0    1A
1    1B
2    1C

 point_gdf
      ID
0     1A
1     1A
2     1A
3     1A
4     1A
5     1B
6     1B
7     1B
8     1B
9     1B
10    1B
11    1B
12    1B
13    1B
14    1C    
15    1C
16    1C
17    1C    
18    1C
19    1C
20    1C    
21    1C
22    1C

有没有办法计算在缓冲区 ID=1A 内有多少 ID=1A 的点,在缓冲区 ID=1B 内有多少 ID=1B 的点,在缓冲区 ID=1C 内有多少 ID=1C 的点,以及很快... 我有超过 20000 个缓冲区和超过 300000 个点。

我正在使用 pandas,但我也可以使用 R。

对不起,我没有提到某些点在缓冲区之外。我只需要缓冲区内的那些

【问题讨论】:

  • point_gdf['ID'].value_counts() 你在找什么?
  • @rhug123 不,因为有些点在缓冲区之外:(
  • buffer_gdf.join(point_gdf['ID'].value_counts(),on='ID',rsuffix = 'count'_) 应该可以,但我还没有测试过。
  • 你对 R 中的data.table 开放吗?如果是这样,我有一个强大的单线herebuffer_gdf[point_gdf, on = .(ID), nomatch = 0][, .N, by = ID],其中数据集是data.tables。

标签: r pandas buffer geopandas


【解决方案1】:

这里是R中的一种方式

sapply(buffer_gdf$ID, function(x) sum(point_gdf$ID == x))
1A 1B 1C 
 5  9  9 

outer

rowSums(outer(buffer_gdf$ID, point_gdf$ID, `==`))
[1] 5 9 9

如果这不应该考虑buffer_gdftable 就足够了

table(point_gdf$ID)

或者做一个subset然后得到table

with(point_gdf, table(ID[ID %in% buffer_gdf$ID]))

数据


buffer_gdf <- structure(list(ID = c("1A", "1B", "1C")), class = "data.frame", row.names = c("0", 
"1", "2"))

point_gdf <- structure(list(ID = c("1A", "1A", "1A", "1A", "1A", "1B", "1B", 
"1B", "1B", "1B", "1B", "1B", "1B", "1B", "1C", "1C", "1C", "1C", 
"1C", "1C", "1C", "1C", "1C")), class = "data.frame", row.names = c("0", 
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", 
"13", "14", "15", "16", "17", "18", "19", "20", "21", "22"))

【讨论】:

    【解决方案2】:

    使用以下方法获取您的价值计数:

    counts = point_gdf.value_counts()
    

    然后reset_index 并在counts 上合并您的buffer_gdf 以附加您的总和:buffer_gdf.merge(counts.reset_index(), on='ID', how='left', validate='1:1')1

    你可以这样写:

    buffer_gdf.merge(point_gdf.value_counts().reset_index(), on='ID',
                     how='left', validate='1:1')
    

    1您不需要指定validate='1:1'。在编写合并时,我几乎总是提供一个 validate 关键字,以确保数据的格式符合我的预期。我认为这是一种最佳做法。

    【讨论】:

      【解决方案3】:

      这是一个具有data.tableperformanceINNER JOIN 的优雅的解决方案。

      解决方案

      鉴于您的示例数据,此处转载为data.tables

      buffer_gdf <- structure(list(ID = c("1A", "1B", "1C")),
                              row.names = c(NA, -3L), class = c("data.table"))
      
      
      point_gdf <- structure(list(ID = c("1A", "1A", "1A", "1A", "1A", "1B", "1B", "1B", "1B", "1B", "1B", "1B", "1B", "1B", "1C", "1C", "1C", "1C", "1C", "1C", "1C", "1C", "1C")),
                             row.names = c(NA, -23L), class = c("data.table"))
      

      以下方法

      library(data.table)
      
      
      # ...
      # Code to generate 'buffer_gdf' and 'point_gdf' as data.tables.
      # ...
      
      
      #         |----------- INNER JOIN -----------||--- Count ---|
      buffer_gdf[point_gdf, on = .(ID), nomatch = 0][, .N, by = ID]
      

      应该产生这样的输出:

         ID N
      1: 1A 5
      2: 1B 9
      3: 1C 9
      

      注意

      如果您的数据集还不是data.tables,请在操作之前使用as.data.table() 对其进行转换。

      如果你愿意,可以在计数时自定义header:[, .(Count_Name = .N), by = ID]

      【讨论】:

        【解决方案4】:

        为什么不join 表格并通过groups 获得count。下面是代码。

        point_gdf %>% inner_join(buffer_gdf , by = "ID") %>% group_by(ID) %>%
          summarise(count = n())
        

        【讨论】:

        • 我喜欢这个优雅的概念,但dplyr 能承受如此庞大的数据量吗?也许data.table 会提供更好的性能...
        • @Greg 坦率地说,如果性能是你要找的,我不会依赖 R
        • @ifly6 你有熊猫、崩溃和 data.table 的基准吗?
        【解决方案5】:

        非常感谢大家的帮助。但是,对我来说最好和有用的答案是this post

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-03
          • 1970-01-01
          • 1970-01-01
          • 2020-02-26
          • 1970-01-01
          • 1970-01-01
          • 2018-06-18
          • 1970-01-01
          相关资源
          最近更新 更多