Pandas Dataframe迭代

时间:2015-09-13 23:10:49

标签: python pandas

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

我有两个.csv文件:一个是有趣的基因列表,另一个是~17,000个基因的主列表,有4个相关的度量列(浮点数)。我使用pandas创建了一个主数据框(键是基因名称),并使用.loc将其传递给我有趣的基因列表。我的new_df是来自该迭代过程的结果数据帧。不可否认,这可能是一种更惯用的方式(即将大熊猫系列与数据帧合并)。

使用new_df我想重新采样master_df搜索和分类相似的基因。我正在寻找基因值,这些基因的值在我的四个列的每个有趣基因值的5%范围内。当我找到匹配项时,它会在我的new_df中的正确密钥下进行分箱。是否有大熊猫的方法来实现这种层次索引?或许这是一本新词典的任务? 谢谢你的指导!

以下是一段代码:

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():

1 个答案:

答案 0 :(得分:0)

这是你之后的事吗?如果是这样,我可以在编辑中提供更详细的说明。如果没有,请说明样本数据和所需结果。

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()语句。当块终止时它将自动关闭。