好的,所以这是我的问题。我有一个由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
中重复,因此按原样存储。第三项在a
(a
和a[2]
)中被找到两次,并存储了第三个浮点数(a[8]
)。新列表中的其余项目未在(1.+0.5)/2.=0.75
中重复显示,因此它们也未经修改而存储。
由于我知道在循环浏览时更新/修改列表不建议使用,因此我选择使用多个临时列表。这是我提出的代码:
a
这段代码有效,但我想知道是否有更优雅/ pythonic的方法可以做到这一点。它只是看起来太复杂了(Fortran-esque,我会说)。
答案 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
这个问题很普遍,它只是一个单行程。您可以使用命名列,计算大量其他有用的统计信息,处理缺失的数据等。