[英]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
中選擇a
與As0
中的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.