【问题标题】:Pandas Dataframe Iterating熊猫数据框迭代
【发布时间】:2015-12-09 21:36:49
【问题描述】:

长时间的听众第一次来电。我在 OS 10.9 上使用 Python 2.7。

我有两个 .csv 文件:一个是有趣基因的列表,另一个是包含约 17,000 个基因的主列表,其中包含 4 个相关的指标列(浮点数)。我使用 pandas 创建了一个主数据框(键是基因名称),并使用 .loc 将我感兴趣的基因列表传递给它。我的 new_df 是来自该迭代过程的结果数据框。诚然,这样做可能有一种更惯用的方式(即将熊猫系列与数据框合并)。

我想使用 new_df 对 master_df 重新采样以搜索和分箱相似的基因。我正在寻找四列中每列的值在我感兴趣的基因值的 5% 以内的基因。当我找到匹配项时,它会在我的 new_df 中的正确键下分箱。有没有一种熊猫方法可以通过分层索引来实现这一点?或者也许这是一本新词典的任务? 感谢您的指导!

这是一段sn-p代码:

import pandas as pd

def list_getter():
    gene_list = []
    with open('experiment.csv', 'U') as f:
        for i in f:
            gene_list.append(i)
        gene_list[:] = [line.rstrip('\n') for line in gene_list]
        return gene_list
        f.close()

def master_df():
    master_df = pd.read_csv('Gene_Metrics_to_Consider.csv', index_col=0) #index by gene name

def gene_find(gene_list, df2):
    '''takes list of genes, returns new dataframe with extracted metrics'''
    for i in gene_list: #find genes and associated metrics
        new_df = df2.loc[gene_list] #NaN returned for genes not found
    return new_df

def bin_similar_genes():

【问题讨论】:

  • 摘录一些您迄今为止所做的代码,这将有助于指导您...还可以考虑使用网络上的一些可访问数据,以便我们帮助您改进代码。
  • 请考虑生成MCVE 以获得更好/更快的答案。

标签: python pandas


【解决方案1】:

这就是你所追求的吗?如果是这样,我可以在编辑中提供更详细的解释。如果不是,请用样本数据和期望的结果进行说明。

import numpy as np
import pandas as pd

gene_master = pd.DataFrame(np.random.randn(5,4), index=list('ABCDE'))

>>> gene_master
          0         1         2         3
A  0.156349  1.230291  1.202380 -0.387327
B -0.302303 -1.048553 -1.420018 -1.706270
C  1.950775 -0.509652 -0.438074 -1.252795
D  0.777490 -1.613898 -0.212740 -0.895467
E  0.386902 -0.510805 -1.180632 -0.028182

让我们创建一个基因列表,其中前两个是紧密匹配的,而其他三个不是。

np.random.seed(0)
genes.iloc[:2] *= (1 + np.random.random([2, 4]) / 100)
genes.iloc[2:] *= (1 + np.random.random([3, 4]))

我将索引更改为一些随机标识符:

genes.index = list('uvwxyz')
>>> genes
           0          1         2         3
v   0.158937   1.256877  1.224254 -0.393693
w  -0.306161  -1.069002 -1.438741 -1.752327
x  14.770935  -1.349448 -2.519776 -4.477268
y   2.997576 -11.523171 -0.261374 -1.150517
z   0.410848  -3.143927 -6.637809 -0.184293

对于给定的耐受性(例如 5%),我认为可能有多个相似的基因。我使用字典理解来遍历与主数据库进行比较的每个基因(我将后者除以前者)。然后,我查找所有四列的差异小于 5% 的行。

tolerance = 0.05
matches = {gene_id: gene_master[(gene_master.div(genes.ix[gene_id].values) - 1)
                    .abs()
                    .lt(tolerance)
                    .gt(0)  # prevents inclusion of identical gene.
                    .all(axis=1)].index.tolist()
           for gene_id in genes.index}

现在只需删除未找到匹配项的所有空结果:

matches = {gene_id: vals for gene_id, vals in matches.iteritems() if len(vals) > 0}
>>> matches
{'v': ['A'], 'w': ['B']}

现在我们可以将其转换回 DataFrame:

idx1 = []
idx2 = []
_ = [idx1.extend([gene_id] * len(gene_ids)) for gene_id, gene_ids in matches.iteritems()]
_ = [idx2.extend(gene_ids) for gene_ids in matches.itervalues()]
matches_df = pd.DataFrame({'gene_id': idx1, 'master_gene_id': idx2})
matches_df['gene_id'] = idx1
matches_df['master_gene_id'] = idx2
matches_df.set_index('gene_id', inplace=True)
>>> matches_df
        master_gene_id
gene_id               
w                    B
v                    A

另外,使用with open() as f: 结构,您不需要f.close() 语句。当块终止时它会自行关闭。

【讨论】:

  • 对我的代码的第一部分非常有帮助(即传入一个列表并输出所需的内容。谢谢,我会重新调整它。
  • 首要问题是:获取我的 new_df 并通过 master_df 搜索可能是“双胞胎”的基因。也就是说,它们的 4 个值非常相似(每个值都在我在实验.csv 中列出的一个感兴趣的基因的 5% 以内)。
  • 所以您的基因列表也有 4 列,并且您正在尝试找到最接近的匹配项?
  • 亚历山大,这非常有帮助!我可能需要一些时间来评估和申请。我会回来报告的。我主动称这个问题已回答。请让我知道是否有其他方法可以投票和给予积极反馈!
  • 我需要一些关于这段代码的额外帮助:字典理解按预期工作,但它也(正确地)从主列表中识别自己。也就是说,我的gene_list 的每个成员都在master metrics 列表中标识了自己(因为它显然符合公差阈值)。放置 if 语句或类似语句的最佳位置在哪里,可以让我忽略 master_df 中的相同密钥,而不是将相同的密钥分箱?提前致谢。这感觉像是一个简单的问题,但我没有在 dict 理解中创建正确的语法。
猜你喜欢
  • 2020-05-17
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2020-01-14
  • 2021-09-17
  • 1970-01-01
相关资源
最近更新 更多