Pandas分组后DataFrame列名缺失及列表访问问题
分组DataFrame生成数组列的问题解决方案
问题1:如何访问现有DataFrame中的locus/AF_afr列表?
你当前生成的DataFrame列名是默认的0、1、2,分别对应lambda返回列表里的locus、AF_afr、AF_nfe数组。可以通过列索引直接访问:
- 获取所有基因对应的locus列表:
variants_gene_list[0] - 获取AF_afr列表:
variants_gene_list[1] - 获取AF_nfe列表:
variants_gene_list[2]
不过这种数字索引的方式不够直观,更推荐直接给DataFrame加上明确列名,之后用字段名访问会更清晰。
问题2:新DataFrame无列名是哪里出了问题?
你的代码里,lambda x返回的是一个普通Python列表,当调用apply(pd.Series)时,pandas会把列表的每个元素拆成一列,但列表本身没有命名信息,所以pandas只能给列分配默认的数字索引(0、1、2),自然就没有对应的字段名了。
优化后的代码(直接生成带列名的DataFrame)
想要一步到位生成带明确列名的结果,有两种更清晰的写法:
写法1:在lambda中返回带列名的Series
这种方式最直观,直接把每个字段的数组对应到指定列名:
import pandas as pd variants_gene_list = data.groupby('gene').apply( lambda x: pd.Series({ 'locus': list(x['locus']), 'AF_afr': list(x['AF_afr']), 'AF_nfe': list(x['AF_nfe']) }) )
之后访问就非常清晰了,比如获取某个基因的locus列表:variants_gene_list.loc['目标基因名', 'locus'],或者获取所有locus列:variants_gene_list['locus']
写法2:给apply(pd.Series)指定columns参数
如果你想保留原来的列表返回方式,也可以在转Series时直接指定列名:
variants_gene_list = data.groupby('gene').apply( lambda x: [list(x['locus']), list(x['AF_afr']), list(x['AF_nfe'])] ).apply(pd.Series, columns=['locus', 'AF_afr', 'AF_nfe'])
这样生成的DataFrame同样会有明确的列名,后续访问逻辑和上面一致。
内容的提问来源于stack exchange,提问作者chucha
相关产品推荐
相关产品推荐

