0

さて、これが私の問題です。それぞれ要素(フロート)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]]

このリストをループして、同じ最初の 2 つのフロートを共有するアイテムを、3 番目のフロートを格納する前に平均化する必要がある同じアイテムとして特定する必要があります。これは、アイテムが以前に繰り返されているとすでに識別されているかどうかを確認する必要があることを意味します。そのため、新しいアイテムとして再度識別しません。

私の言いたいことをより明確にするために、処理リストの出力は次の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]) で 3 回識別されたため、3 番目の float の平均 ( (0.7+0.3+1.)/3. = 0.67) で格納されたことに注意してください。2番目のアイテムは繰り返されなかったaので、そのまま保管されていました。3 番目の項目はa(a[2]およびa[8]) で 2 回検出され、3 番目の float を平均化して格納されました ( (1.+0.5)/2.=0.75)。新しいリストの残りの項目は、繰り返されたものとして検出されなかったaため、変更なしで保存されました。

リストをループしながら更新/変更することはお勧めできないことを知っているので、いくつかの一時リストを使用することにしました。これは私が思いついたコードです:

import numpy as np

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]]

# Final list.
a_processed = []

# Holds indexes of elements to skip.
skip_elem = []

# Loop through all items in a.
for indx, elem in enumerate(a):
    temp_average = []
    temp_average.append(elem)        
    # Only process if not found previously.
    if indx not in skip_elem:
        for indx2, elem2 in enumerate(a[(indx+1):]):
            if elem[0] == elem2[0] and elem[1] == elem2[1]:
                temp_average.append(elem2)
                skip_elem.append(indx2+indx+1)

        # Store 1st and 2nd floats and averaged 3rd float.
        a_processed.append([temp_average[0][0], temp_average[0][1],
                            round(np.mean([i[2] for i in temp_average]),2)])

このコードは機能しますが、これを行うためのよりエレガントで Pythonic な方法があるかどうか疑問に思っています。そのままでは複雑すぎるように見えます(Fortran風だと思います)。

4

2 に答える 2

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

この問題は、ワンライナーであるほど一般的です。名前付き列を使用したり、他の有用な統計のホストを計算したり、欠損データを処理したりできます。

于 2013-10-24T16:25:02.800 に答える
4

defaultdictを使用して、各サブリストの最初の 2 つの要素から 3 番目のすべての項目への辞書を作成することで、コードをより簡潔で読みやすくすることができると思います。

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 で指摘されているように を使用できます。

于 2013-10-24T15:56:56.337 に答える