我正在使用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而不会丢失其他列中的信息?
答案 0 :(得分:1)
简单解决方案:
将transcript_id
,gene_id
和gene_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_id
,gene_id
和gene_name
合并到另一列,例如merged_id
和{{ 1 {} groupby
。在计算结束时将列拆分为组件。
聚苯乙烯。我建议使用Simple Solution。