相当于 R/dplyr group_by 的 Pandas 汇总连接
Posted
技术标签:
【中文标题】相当于 R/dplyr group_by 的 Pandas 汇总连接【英文标题】:Pandas equivalent of R/dplyr group_by summarise concatenation 【发布时间】:2022-01-10 06:32:33 【问题描述】:我有一个操作需要从 R 中的 dplyr
(和 stringr
)转换为 python 中的 pandas
。在 R 中这很简单,但我无法在 pandas 中绕开它。基本上,我需要按一个(或多个)列分组,然后将剩余的列连接在一起并用分隔符折叠它们。 R 有很好的矢量化 str_c
函数,它完全符合我的要求。
这是 R 代码:
library(tidyverse)
df <- as_tibble(structure(list(file = c(1, 1, 1, 2, 2, 2), marker = c("coi", "12s", "16s", "coi", "12s", "16s"), start = c(1, 22, 99, 12, 212, 199), end = c(15, 35, 102, 150, 350, 1102)), row.names = c(NA, -6L), class = "data.frame") )
df %>%
group_by(file) %>%
summarise(markers = str_c(marker,"[",start,":",end,"]",collapse="|"))
#> # A tibble: 2 × 2
#> file markers
#> <dbl> <chr>
#> 1 1 coi[1:15]|12s[22:35]|16s[99:102]
#> 2 2 coi[12:150]|12s[212:350]|16s[199:1102]
这里是python代码的开始。我认为agg
或transform
存在一些诡计,但我不确定如何组合和加入多个列:
from io import StringIO
import pandas as pd
s = StringIO("""
file,marker,start,end
1.f,coi,1,15
1.f,12s,22,35
1.f,16s,99,102
2.f,coi,12,150
2.f,12s,212,350
2.f,16s,199,1102
""")
df = pd.read_csv(s)
# ... now what? ...
【问题讨论】:
你也可以检查 siuba 或 dplython 【参考方案1】:(df.astype(str)
.assign(markers = lambda df: df.marker + "[" + (df.start + ":"+df.end) + "]")
.groupby('file', as_index=False)
.markers
.agg("|".join)
)
file markers
0 1.f coi[1:15]|12s[22:35]|16s[99:102]
1 2.f coi[12:150]|12s[212:350]|16s[199:1102]
想法是先组合列,然后再使用python的str.join方法进行分组和聚合
【讨论】:
您需要 lambda,因为开始时数据类型发生了变化 (astype
)。当然,如果 df 是一个字符串,我不会费心去改变
我必须删除 as_index=False
部分才能使其正常工作。否则,它会成功!【参考方案2】:
创建连接标记和最后两列的新列标记,由:
按文件分组并连接新的列标记。
df['markers']=df['marker']+'['+(df.astype(str).iloc[:,2:].agg(list,1).str.join(':'))+']'
df.groupby('file')['markers'].apply(lambda x: x.str.cat(sep='|')).to_frame()
markers
file
1.f coi[1:15]|12s[22:35]|16s[99:102]
2.f coi[12:150]|12s[212:350]|16s[199:1102]
【讨论】:
以上是关于相当于 R/dplyr group_by 的 Pandas 汇总连接的主要内容,如果未能解决你的问题,请参考以下文章