0

我正在尝试从多个打开的文件创建列表,但遇到了一些问题。我需要为每个文件创建两个单独的列表,现在我的代码只为最后一个迭代的文件创建两个列表。建议修复并为“file_list”中的每个文件创建唯一的“sample_genes”和“sample_values”?

或者,为所有文件中的“gene_names”和所有文件中的“sample_values”创建一个统一列表也可以。

# Parse csv files for samples, creating lists of gene names and expression values.
file_list =  ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv']
des_list = ['a', 'b', 'c', 'd', 'e', 'f']
for idx, (f_in, des) in enumerate(zip(file_list, des_list)):
    with open(f_in) as des:
        cread = list(csv.reader(des, delimiter = '\t'))
        sample_genes = [i for i, j in (sorted([x for x in {i: float(j) 
                                        for i, j in cread}.items()], key = lambda v: v[1]))]        
        sample_values = [j for i, j in (sorted([x for x in {i: float(j) 
                            for i, j in cread}.items()], key = lambda v: v[1]))]

# Compute row means.
mean_values = [((a + b + c + d + e + f)/len(file_list)) for i, (a, b, c, d, e, f) in enumerate(zip(sample_1_values, sample_2_values, sample_3_values, sample_4_values, sample_5_values, sample_6_values))]

# Provide proper gene names for mean values and replace original data values by corresponding means.
sample_genes_list = [i for i in sample_1_genes, sample_2_genes, sample_3_genes, sample_4_genes, sample_5_genes, sample_6_genes]

sample_final_list = [sorted(zip(sg, mean_values)) for sg in sample_genes_list]

下面的新代码:

# Parse csv files for samples, creating lists of gene names and expression values.
file_list =  ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv']
full_dict = {}
for path in file_list:
    with open(path) as stream:
            data = list(csv.reader(stream, delimiter = '\t'))
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1])
    sample_genes = [i for i, j in data]
    sample_values = [j for i, j in data]
    full_dict[path] = (sample_genes, sample_values)

在字典中解包字典的结果显示了一些深层嵌套结构:

for key in full_dict: 
value = full_dict[key]
for key in full_dict[key]:
    for idx, items in enumerate(key):
        print idx
4

2 回答 2

3

我不确定您的 csv 文件中有什么,但您正在做一些多余的工作和一些毫无意义的工作。让我们分解一下:

for idx, (f_in, des) in enumerate(zip(file_list, des_list)):

idx根本不会出现在循环体中,所以你不需要enumerate.

des确实出现在列表的主体中,但它的第一次出现是在结构中:

with open(f_in) as des:

因此循环内的那个是不同的des,是打开文件的流。所以大概你也不需要zip。放弃两者,你可以这样做:

for f_in in file_list:

接下来,您读取文件一次 ( list(csv.reader(...)),这很好。结果保存在 name 下cread

然后你让这两个列表推导运行在 的结果上sorted,它本身是一个列表推导的结果,它在应用于.items()字典推导的结果上运行。外部列表推导的要点是从列表中提取一个或另一个项目: first i, then j, from [... for i, j in ...]

根据 内部发生的情况,这可能是合适的sorted,所以让我们看一下:

sorted(..., key = lambda v: v[1])

这意味着列表元素本身必须是可索引的,并且您按第二项排序(v[0]当然是第一项)。

当您按第二项排序,然后取第一项并丢弃第二项时,至少不是多余的。但是,如果您按第二项排序,然后取第二项并丢弃第一项,则可以简单地取第二项,然后排序并完成。(但在我们走那么远之前,让我们再检查一件事。:-))

最后,让我们看看字典推导和.items()调用。dictcomp 本身在这两种情况下都是:

{i: float(j) for i, j in cread}

据推测,您的 CSV 文件必须为您提供配对,并且第一部分中的任何内容都可以用作密钥,而第二部分中的任何内容都可以转换为float. 因此,让我们使用一个简单的字典,其中包含两个键值对,例如字符串和浮点数:

{'a': 2.71828, 'b': 3.14159}

并申请.items()

>>> {'a': 2.71828, 'b': 3.14159}.items()
[('a', 2.71828), ('b', 3.14159)]

您可以只使用列表推导式来制作两元素元组,而不是组成字典并将其折叠回二元素元组的列表。让我们测试一下:

>>> cread = [['a', '2.71828'], ['b', '3.14159']]
>>> [(i, float(j)) for i, j in cread]
[('a', 2.71828), ('b', 3.14159)]

现在我们可以通过它的第二个元素对这个东西进行一次排序。我们可以使用sorted, 或制作一个列表并就地排序,但是一旦我们完成了,让我们保存它。在我们开始之前,我选择了一组错误的值,因为它们已经排序,让我们添加一对以不同方式排序的 cread:

>>> cread.append(['c', '0']); print cread
[['a', '2.71828'], ['b', '3.14159'], ['c', '0']]
>>> by_second = sorted([(i, float(j)) for i, j in cread], key = lambda v: v[1])
>>> by_second
[('c', 0.0), ('a', 2.71828), ('b', 3.14159)]

保存了这个排序后,我们现在可以通过原始 list-comprehension-to-pick-item 获取 sample_genes 和 sample_values 列表。我也要改几个名字:

for path in file_list:
    with open(path) as stream:
        data = list(csv.reader(stream, delimiter = '\t'))
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1])
    sample_genes = [i for i, j in data]
    sample_values = [j for i, j in data]

下一步当然是以某种方式保存这些样本。大概您打算使用它们idxdes_list命名它们,但通过 csv-path-name 索引它们似乎更直接:

    somedict[path] = (sample_genes, sample_values)

wheresomedict最初是一个空字典(在进入for循环之前创建)。不过,在某些时候开始考虑适当的数据结构并创建一个类是合理的。

于 2013-05-26T01:39:36.590 回答
0

不知道我是否看到了问题,你不能这样做

sample_genes[idx]  = [i for i, j in (....
sample_values[idx] = [j for i, j in (....

或者sample_genes[des]如果您更喜欢命名属性?

于 2013-05-26T01:29:31.417 回答