缓冲区内具有相同 id 的点

Points within buffer with the same id

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

 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。

抱歉,我没有提到有些点在缓冲区之外。我只需要缓冲区内的那些

这是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"))

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

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'。我几乎总是在编写合并时提供一个验证关键字,以确保数据按照我期望的方式进行格式化。我认为这是最佳做法。

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

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

这是一个具有 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.table,请在操作前使用 as.data.table() 转换它们。

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

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