优雅地从主列表中的子列表中获取信息

时间:2013-10-24 15:46:14

标签: python list numpy

好的,所以这是我的问题。我有一个由N个子列表组成的列表,每个子列表由M个元素(浮点数)组成。因此,在一般形式中,它看起来像这样:

a_list = [b_list_1, b_list_2, ..., b_list_N]

使用:

b_list_i = [c_float_1, c_float_2, ..., c_float_M]

对于此示例假设为N=9 ; M=3,因此列表如下所示:

a = [[1.1, 0.5, 0.7], [0.3, 1.4, 0.2], [0.6, 0.2, 1.], [1.1, 0.5, 0.3], [0.2, 1.1, 0.8], [1.1, 0.5, 1.], [1.2, 0.3, 0.6], [0.6, 0.4, 0.9], [0.6, 0.2, 0.5]]

我需要遍历此列表,以识别那些共享相同的前两个浮动的项目,作为存储之前应该平均第三个浮点数的相同项目。这意味着我应该检查一个项目是否已被识别为先前已重复,因此我不会将其再次识别为新项目。

为了更清楚地了解我的意思,这就是处理列表a的输出应该是这样的:

a_processed = [[1.1, 0.5, 0.67], [0.3, 1.4, 0.2], [0.6, 0.2, 0.75], [0.2, 1.1, 0.8], [1.2, 0.3, 0.6], [0.6, 0.4, 0.9]]

请注意,此新列表中的第一个项目在(a[0]a[3]a[5])中被识别三次,因此它存储了第三个浮点数({{ 1}})。第二项未在(0.7+0.3+1.)/3. = 0.67中重复,因此按原样存储。第三项在aaa[2])中被找到两次,并存储了第三个浮点数(a[8])。新列表中的其余项目未在(1.+0.5)/2.=0.75中重复显示,因此它们也未经修改而存储。

由于我知道在循环浏览时更新/修改列表不建议使用,因此我选择使用多个临时列表。这是我提出的代码:

a

这段代码有效,但我想知道是否有更优雅/ pythonic的方法可以做到这一点。它只是看起来太复杂了(Fortran-esque,我会说)。

2 个答案:

答案 0 :(得分:4)

我认为通过使用defaultdict从每个子列表中的前两个元素到所有第三个项目创建字典,您当然可以使您的代码更简洁,更易于阅读:

from collections import defaultdict
nums = defaultdict(list)
for arr in a:
    key = tuple(arr[:2]) # make the first two floats the key
    nums[key].append( arr[2] ) # append the third float for the given key

a_processed = [[k[0], k[1], sum(vals)/len(vals)] for k, vals in nums.items()]

使用它,我获得与你相同的输出(虽然顺序不同):

[[0.2, 1.1, 0.8], [1.2, 0.3, 0.6], [0.3, 1.4, 0.2], [0.6, 0.4, 0.9], [1.1, 0.5, 0.6666666666666666], [0.6, 0.2, 0.75]]

如果a_processed的顺序存在问题,您可以使用OrderedDict,正如@DSM所指出的那样。

答案 1 :(得分:4)

为了比较,这是pandas方法。如果这确实是幕后的数据处理问题,那么你可以节省很多时间。

>>> a
[[1.1, 0.5, 0.7], [0.3, 1.4, 0.2], [0.6, 0.2, 1.0], [1.1, 0.5, 0.3], [0.2, 1.1, 0.8], [1.1, 0.5, 1.0], [1.2, 0.3, 0.6], [0.6, 0.4, 0.9], [0.6, 0.2, 0.5]]
>>> df = pd.DataFrame(a)
>>> df.groupby([0,1]).mean()
                2
0   1            
0.2 1.1  0.800000
0.3 1.4  0.200000
0.6 0.2  0.750000
    0.4  0.900000
1.1 0.5  0.666667
1.2 0.3  0.600000

这个问题很普遍,它只是一个单行程。您可以使用命名列,计算大量其他有用的统计信息,处理缺失的数据等。