簡體   English   中英

Python One襯板可用於未排序列表的多個平均值

[英]Python one liner for multiple averages of unsorted list

我有以下形式的數據

Ns0 = [ 2 3 1 2 2 3 4 5 3 1 2 ]
As0 = [ 9 2 4 5 4 3 1 2 0 8 2 ]

我想創建Ns = [ 1 2 3 4 5 ]以及As_avg ,它是與As0相關聯的Ns0中所有項的平均值。

我知道我可以使用Ns = list(set(Ns0))來創建Ns ,我希望通過以下方式制作As_avg

for N in Ns:
    As_avg.append( np.mean( np.array( [a for a in As0 if ??? ] ) ) )

但我被困在??? 一部分。 如何在As0中選擇aAs0中的N相對應的Ns0

我知道我可以按照以下方式進行操作:

for N in Ns:
    tlist = []
    for (tN, tA) in zip(Ns0, As0):
        if( tN == N ):
            tlist.append(tA)
    As_avg.append( np.mean( np.array( tlist ) ) )

但是我希望有一種更pythonic的方式來做到這一點

for N in Ns:
    As_avg.append( np.mean( np.array( [tA for tN, tA in zip(Ns0, As0) if tN == N]  ) ) )

但是,如果要在可讀性上進行權衡,請不要嘗試使用“ pythonic”。 我個人更喜歡2循環版本。

您可以使用字典來保存期望的項,這些項的鍵是Ns0中的唯一項,值是As0中相應項的As0 ,然后使用map函數將np.mean應用於值:

>>> d = {}
>>> 
>>> for i,j in zip(Ns0, As0):
...     d.setdefault(i, []).append(j)
... 
>>> map(np.mean, d.values())
[6.0, 5.0, 1.6666666666666667, 1.0, 2.0]

請注意 ,此方法的優點是您不必從Ns0創建唯一項列表,然后可以簡單地使用一個循環。

請記住,可讀性是Python的關鍵價值之一https://www.python.org/dev/peps/pep-0020/

列表和字典理解對此可能非常有用,但是如果它們太復雜了,它們將變得很難閱讀,您應該將它們分成多行。

我認為這是解決問題的方法:

common_vals = [A_val for A_val, N_val in zip(As0, Ns0) if A_val == N_val]
As_avg = np.mean(np.asarray(common_vals))

我假設您只希望common_vals包含出現在兩個列表中的值,並且出現在相同位置。 如果只希望兩個列表中都出現值:

common_vals = [val for val in As0 if val is in Ns0]

我還要指出,變量名中的大寫字母通常在Python中是不好的,因為它違反了PEP8樣式指南https://www.python.org/dev/peps/pep-0008/如果您要處理矩陣不過,我可以理解大寫有時更有意義:)

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM