在熊猫组中保留有害的coliumns

时间:2015-11-24 17:37:27

标签: python pandas

我正在使用pandas处理中等大小的数据集。它有大约600,000行。

它有三个“id”变量:“gene_id”,“gene_name”和“transcript_id”,然后是许多在运行时确定的数字列。

In [129]: df.head().todict()
{u'utr3_count': {8: 2.0, 30: 1.0, 29: 2.0, 6: 2.0, 7: 2.0}, 
 u'gene_id': {8: u'ENSG00000188157', 30: u'ENSG00000160087', 29: u'ENSG00000176022', 6: u'ENSG00000188157', 7: u'ENSG00000188157'}, 
 u'utr3_enrichment': {8: 2.1449912126499999, 30: 1.14988290398, 29: 1.0484234234200001, 6: 2.1449912126499999, 7: 2.1449912126499999},
 u'transcript_id': {8: u'ENST00000379370', 30: u'ENST00000450390', 29: u'ENST00000379198', 6: u'ENST00000379370', 7: u'ENST00000379370'},
 u'expression': {8: 0.13387876534027521, 30: 0.514855687606112, 29: 0.79126387397064091, 6: 0.13387876534027521, 7: 0.13387876534027521}, 
 u'gene_name': {8: u'AGRN', 30: u'UBE2J2', 29: u'B3GALT6', 6: u'AGRN', 7: u'AGRN'}}

我想获得每个“transcript_id”的重复的平均值。但是通过分组“transcript_id”这样做意味着我丢失了关于“gene_id”和“gene_name”的信息,因为它们被归类为讨厌的列。

如果我对所有三列进行分组,我会立即得到MemoryError,即使在一个大盒子(128GB)上,因为pandas会尝试对三列中每个值的组合进行计算,即使这绝对不是必需的:每个“transcript_id”映射到单个“gene_id”和单个“gene_name”。

有没有办法在transcript_id上进行groupby而不会丢失其他列中的信息?

1 个答案:

答案 0 :(得分:1)

简单解决方案:

transcript_idgene_idgene_name存储在单独的DataFrame中(例如metadata):

metadata = df[['transcript_id', 'gene_id', 'gene_name']].copy()
# .copy() is important!
正如您现在所做的groupby上的{p> transcript_id,并执行计算(比如agg_df)。完成后,将两个框架合并在一起:

pd.merge(agg_df, metadata, how='left', on='transcript_id)

这是因为

  

...每个" transcript_id"映射到单个" gene_id"还有一个   " gene_name"

替代解决方案:

使用pd.read_csv(file_path, chunksize = <some integer, say 5e4>)以块为单位读取文件(假设您正在读取csv)。在所有三列上groupby,(您现在不会遇到MemoryError,因为您只是在阅读部分数据)并继续运行总计和运行计数。将总数除以最后的计数。伪代码:

totals = pd.DataFrame()
counts = pd.DataFrame()
df = pd.read_csv(file_path, chunksize=5e4)
for chunk in df:
    grouped = chunk.groupby(['transcript_id', 'gene_id', 'gene_name'])
    totals = totals.add(grouped.sum())
    counts = counts.add(grouped.count())
means = totals/counts

只要您需要一些可以按比例计算的度量,例如总和,计数,产品,累计金额和产品,这将有效。但是像百分位数或

这样的东西

另一个解决方案(稍微难点):将列transcript_idgene_idgene_name合并到另一列,例如merged_id和{{ 1 {} groupby。在计算结束时将列拆分为组件。

聚苯乙烯。我建议使用Simple Solution。