2

我对 pandas 和 python 很陌生,而且我来自生物化学和药物发现的背景。我想自动化的一项常见任务是将药物治疗和蛋白质组合列表转换为包含所有此类组合的格式。

例如,如果我有一个包含一组给定组合的 DataFrame: https ://github.com/colinhiggins/dillydally/blob/master/input.csv ,我想把它变成https://github.com /colinhiggins/dillydally/blob/master/output.csv使得每个蛋白质(1、2 和 3)被复制 n 次到输出 DataFrame,其中行数 n 是药物数量和药物浓度加一对于每种蛋白质的无药物行。

理想情况下,组合程度将由指示关系的其他表格决定,例如,如果蛋白质 1 和 2 用药物 1、2 和 3 治疗,但蛋白质 2 不使用任何药物治疗。

我认为loop需要某种嵌套的 for ,但我无法完全了解如何开始它。

4

3 回答 3

2

考虑以下解决方案

from itertools import product
import pandas
protein = ['protein1' , 'protein2' , 'protein3' ]
drug = ['drug1' , 'drug2', 'drug3']
drug_concentration = [100,30,10]

df = pandas.DataFrame.from_records( list( i for i in product(protein, drug, drug_concentration ) ) , columns=['protein' , 'drug' , 'drug_concentration'] )

>>> df
     protein   drug  drug_concentration
0   protein1  drug1                 100
1   protein1  drug1                  30
2   protein1  drug1                  10
3   protein1  drug2                 100
4   protein1  drug2                  30
5   protein1  drug2                  10
6   protein1  drug3                 100
7   protein1  drug3                  30
8   protein1  drug3                  10
9   protein2  drug1                 100
10  protein2  drug1                  30
11  protein2  drug1                  10
12  protein2  drug2                 100
13  protein2  drug2                  30
14  protein2  drug2                  10
15  protein2  drug3                 100
16  protein2  drug3                  30
17  protein2  drug3                  10
18  protein3  drug1                 100
19  protein3  drug1                  30
20  protein3  drug1                  10
21  protein3  drug2                 100
22  protein3  drug2                  30
23  protein3  drug2                  10
24  protein3  drug3                 100
25  protein3  drug3                  30
26  protein3  drug3                  10

这基本上是您所追求的笛卡尔积,这是模块中函数的product功能itertools。诚然,我很困惑为什么你想要那些只列出其他列中带有 nan 的蛋白质的空行。不确定这是故意的还是偶然的。如果数据类型是统一的和数字的,这与所谓的meshgrid功能相似。

于 2018-02-02T02:14:04.743 回答
0

在使用 ShikharDua 推荐的创建字典列表的方法,在 pandas.DataFrame 中添加一行的帮助下,我已经完成了部分工作,每个字典对应于最终 DataFrame 中的一行。

代码是:

data = pandas.read_csv('input.csv')
dict1 = {"protein":"","drug":"","drug_concentration":""} #should be able to get this automatically using the dataframe columns, I think
rows_list = []
for unique_protein in data.protein.unique():
    dict1  = {"protein":unique_protein,"drug":"","drug_concentration":""}
    rows_list.append(dict1)
    for unique_drug in data.drug.unique():
        for unique_drug_conc  in data.drug_concentration.unique():
            dict1  = {"protein":unique_protein,"drug":unique_drug,"drug_concentration":unique_drug_conc}
            rows_list.append(dict1)
df = pandas.DataFrame(rows_list)
df

它不像我希望的那样灵活,因为没有药物的蛋白质的额外行被硬编码到嵌套for循环中,但至少它是一个开始。我想我可以在每个循环中添加一些if语句。for

于 2013-09-08T17:33:57.940 回答
0

我已经改进了早期版本

  1. 将其包含在一个函数中

  2. 添加了对来自另一个输入 CSV 文件的蛋白质的检查,该输入 CSV 文件在 A 列中包含相同的蛋白质,在 B 列中标记为“用药物治疗”中为真或假

  3. 跳过空值。我注意到我的示例 input.csv 具有相等长度的列,如果 NaN 行的长度不相等,该函数开始变得有点疯狂。

  4. 初始字典键是从初始输入 CSV 的列中设置的,而不是对它们进行硬编码。

我用一些真实数据对此进行了测试(因此将 input.csv 更改为 realinput.csv),并且效果很好。

功能齐全的 python 文件的代码如下:

import pandas
import os
os.chdir("path_to_directory_containing_realinput_and_boolean_file")
realinput = pandas.read_csv('realinput.csv')
rows_list = []
dict1 = dict.fromkeys(realinput.columns,"")
prot_drug_bool = pandas.read_csv('protein_drug_bool.csv')
prot_drug_bool.index = prot_drug_bool.protein
prot_drug_bool = prot_drug_bool.drop("protein",axis=1)

def null_check(value):
    return pandas.isnull(value)

def combinator(input_table):
    for unique_protein in input_table.protein.unique():
        dict1 = dict.fromkeys(realinput.columns,"")
        dict1['protein']=unique_protein
        rows_list.append(dict1)
        if prot_drug_bool.ix[unique_protein]:
            for unique_drug in input_table.drug.unique():
                if not null_check(unique_drug):
                    for unique_drug_conc in input_table.drug_concentration.unique():
                        if not null_check(unique_drug_conc):
                            dict1 = dict.fromkeys(realinput.columns,"")
                            dict1['protein']=unique_protein
                            dict1['drug']=unique_drug                        
                            dict1['drug_concentration']=unique_drug_conc
                            rows_list.append(dict1)
    df = pandas.DataFrame(rows_list)
    return df
df2 = combinator(realinput)
df2.to_csv('realoutput.csv')

我仍然希望通过摆脱对任何字典键的硬编码并让用户定义的 input.csv 列标题决定输出来使其更加通用。另外,我想摆脱定义的三列设置来处理任意数量的列。

于 2013-09-09T00:35:27.147 回答