SparkR groupBy 多列,对每个列应用过滤器
SparkR groupBy multiple column with applying filter on each
我有一个包含超过 5 亿条记录的数据集。我想在多个列上应用 group by
子句来获取计数。在分组时,我还需要确保结果计数仅针对列中的特定值。
我有贷款 Table 其中有
customer_id,loan_id,installment_amt,installment_status
Installment_status 包含多个值 'B'、'N'、'C'
在单个查询中,我想知道每个 customer_id、loan_id 的分期付款总数是多少,分期付款次数只有 'B' 和分期付款次数有 'C'.
我是 SparkR 的新手,正在尝试做如下的事情-
RESULT <- summarize(
groupBy(LOAN, "customer_id", "loan_id"),
NO_OF_Installment=count(LOAN$installment_amt),
BILLED_INSTALLMENTS=count(LOAN$$installment_status=='B'),
CCANCELLED_INSTALLMENT=count(LOAN$$installment_status=='C')
)
billed_installment 和 cancelled_installment 的计数相同。
我不太确定计数时过滤是否有效。我在 the documentation 中没有看到任何内容。但我已经看到这段代码在 R 中工作。
我发现 SparkR
代码使用管道更容易阅读,因为它看起来更类似于 Python 或相同的 Scala 版本,所以我将使用 magrittr
.
library(magrittr)
基本思路是使用ifelse
方法。
在 SparkQL 中:
LOAN %>% createOrReplaceTempView('LOAN')
sql("
select customer_id, loan_id, count(installment_amt) as no_of_installment,
count(if(installment_status = 'B', 1, NULL)) as billed_installments,
count(if(installment_status = 'C', 1, NULL)) as cancelled_installments
from loan
group by customer_id, loan_id
") %>% summarize
在"native" SparkR
中应该是:
LOAN %>% groupBy('customer_id', 'loan_id') %>%
summarize(
NO_OF_Installment = count(.$installment_amt),
BILLED_INSTALLMENTS = count(ifelse(.$installment_status == 'B', 1, NA)),
CANCELLED_INSTALLMENTS = count(ifelse(.$installment_status == 'C', 1, NA))
)
我不是 100% 确定您是否需要 NA
或 NULL
作为 ifelse
中的 no
值,但我确实找到了 this使用 NA
.
回答
至于为什么你自己的方法不起作用,我认为你的方法适用于 sum
而不是 count
.
count
计算一列中非 NULL
的行数。 LOAN$installment_status=='C'
是一个 boolean
列,因此如果 LOAN$installment_status
是 NULL
,它只会是 NULL
。 count
不关心列的 实际值 -- 它甚至不关心 数据类型 。
最接近 base
等价于 count
的 R 是 length
。 length(numeric(100))
等同于 length(logical(100))
.
相反,您可能更愿意将其视为 sum
—— base
R 等效项类似于 sum(installment_status == 'B')
。在 SparkR
中,这看起来像
sum(as.integer(.$installment_status == 'B'))
# or
sum(ifelse(.$installment_status == 'B', 1, 0))
不幸的是,当我们 sum
、SparkR
需要显式转换时,base
R 将 logical
类型隐式转换为 integer
,因此这两个替代方案使从 boolean
到 integer
显式转换。
我有一个包含超过 5 亿条记录的数据集。我想在多个列上应用 group by
子句来获取计数。在分组时,我还需要确保结果计数仅针对列中的特定值。
我有贷款 Table 其中有 customer_id,loan_id,installment_amt,installment_status Installment_status 包含多个值 'B'、'N'、'C'
在单个查询中,我想知道每个 customer_id、loan_id 的分期付款总数是多少,分期付款次数只有 'B' 和分期付款次数有 'C'.
我是 SparkR 的新手,正在尝试做如下的事情-
RESULT <- summarize(
groupBy(LOAN, "customer_id", "loan_id"),
NO_OF_Installment=count(LOAN$installment_amt),
BILLED_INSTALLMENTS=count(LOAN$$installment_status=='B'),
CCANCELLED_INSTALLMENT=count(LOAN$$installment_status=='C')
)
billed_installment 和 cancelled_installment 的计数相同。
我不太确定计数时过滤是否有效。我在 the documentation 中没有看到任何内容。但我已经看到这段代码在 R 中工作。
我发现 SparkR
代码使用管道更容易阅读,因为它看起来更类似于 Python 或相同的 Scala 版本,所以我将使用 magrittr
.
library(magrittr)
基本思路是使用ifelse
方法。
在 SparkQL 中:
LOAN %>% createOrReplaceTempView('LOAN')
sql("
select customer_id, loan_id, count(installment_amt) as no_of_installment,
count(if(installment_status = 'B', 1, NULL)) as billed_installments,
count(if(installment_status = 'C', 1, NULL)) as cancelled_installments
from loan
group by customer_id, loan_id
") %>% summarize
在"native" SparkR
中应该是:
LOAN %>% groupBy('customer_id', 'loan_id') %>%
summarize(
NO_OF_Installment = count(.$installment_amt),
BILLED_INSTALLMENTS = count(ifelse(.$installment_status == 'B', 1, NA)),
CANCELLED_INSTALLMENTS = count(ifelse(.$installment_status == 'C', 1, NA))
)
我不是 100% 确定您是否需要 NA
或 NULL
作为 ifelse
中的 no
值,但我确实找到了 this使用 NA
.
至于为什么你自己的方法不起作用,我认为你的方法适用于 sum
而不是 count
.
count
计算一列中非 NULL
的行数。 LOAN$installment_status=='C'
是一个 boolean
列,因此如果 LOAN$installment_status
是 NULL
,它只会是 NULL
。 count
不关心列的 实际值 -- 它甚至不关心 数据类型 。
最接近 base
等价于 count
的 R 是 length
。 length(numeric(100))
等同于 length(logical(100))
.
相反,您可能更愿意将其视为 sum
—— base
R 等效项类似于 sum(installment_status == 'B')
。在 SparkR
中,这看起来像
sum(as.integer(.$installment_status == 'B'))
# or
sum(ifelse(.$installment_status == 'B', 1, 0))
不幸的是,当我们 sum
、SparkR
需要显式转换时,base
R 将 logical
类型隐式转换为 integer
,因此这两个替代方案使从 boolean
到 integer
显式转换。