2017-03-24 24 views
0

私は2016年と2017年のそれぞれに同じ5つのキーを持つデータの2つの辞書を持っています。私は、各キーの値のパーセンテージを辞書の値の合計に換算し、各キーの2つのパーセンテージをラベルに結合したいと考えています。私は以下のようにすることができましたが、私の方法は多くのループを必要とし、やや控えめです。私は、コードをより効率的にするためにコードを凝縮または書き直す方法を探しています。Python - For Loopsを組み合わせる

UsersPerCountry, UsersPerPlatform, UsersPerPlatform2016, UsersPerPlatform2017 = Analytics.UsersPerCountryOrPlatform() 

labels = [] 
sizes16 = [] 
sizes17 = [] 
sumc1 = 0 
sumc2 = 0 
percentages = [] 

for k, v in dict1.iteritems(): 
    sumv1 += v 
for k, v in dict1.iteritems(): 
    v1 = round(((float(v)/sumc1) * 100), 1) 
    percentages.append(v1) 
    labels.append(k) 
    sizes16.append(c) 
for k, v in dict2.iteritems(): 
    sumv1 += v 
for k, v in dict2.iteritems(): 
    v2 = round(((float(v)/sumc1) * 100), 1) 
    percentages.append(v2) 
    sizes17.append(c) 
for i in range(5): 
    labels[i] += (', ' + str(percentages[i]) + '%' + ', ' + str(percentages[i + 5]) + '%') 

これは、ラベルは次のようになります。

enter image description here

EDIT:を私は今、変数宣言を追加しています。私はすべての変数を空のリストまたは0に設定することについてのハッシュされた行で十分だと思いました。

+1

完全なコードスニペットを投稿してください。例えば'sumc1'と' c'は決して宣言されていません... – brianpck

+1

'Pandas'を使うことを考えましたか?それぞれの辞書を 'pd.DataFrame'に入れ、パンダのベクトル化されたメカニズムを使って2行で同じ計算を行うことができます。 'df = pd.DataFrame(dict1)'と 'df2 = pd.DataFrame(dict2)'を組み合わせたり、単一の 'df = pd.concat([df1、df2]、keys = [2016,2017] ) '。 –

答えて

1

パンダのデータフレームクラスを使用すると、物事を単純化できます。私はそれが少し働いたする必要があるが、そうでない場合は、これを試みるかもしれので、あなたのパーセンテージが計算されているかがわからないビットいます:

import pandas as pd 

#convert data to DataFrame class 
df1 = pd.DataFrame(dict1) 
df2 = pd.DataFrame(dict2) 

#compute the percentages 
percnt1 = df1.sum(axis=0).div(df1.sum().sum()) 
percnt2 = df2.sum(axis=0).div(df2.sum().sum()) 

#to get the sum: 
percnt1 + percnt2 

はここでの例です:パンダなし

## create a data frame: 
import numpy as np 
df1 = pd.DataFrame({'Android':np.random.poisson(10,100), 'iPhone':np.random.poisson(10,100), 
'OSX':np.random.poisson(10,100), 'WEBGL':np.random.poisson(10,100), 'Windows':np.random.poisson(10,100)}) 

In [11]: df1.head() 
Out[11]: 
    Android OSX WEBGL Windows iPhone 
0  12 12  9  9  5 
1  9 8  14  7  11 
2  12 10  7  10  11 
3  11 12  7  17  5 
4  15 16  15  11  13 

In [10]: df1.sum(axis=0).div(df1.sum(axis=0).sum()) 
Out[10]: 
Android 0.205279 
OSX  0.198782 
WEBGL  0.200609 
Windows 0.198376 
iPhone  0.196954 
dtype: float64 
1

Pythonの組み込み機能や機能の一部を利用する必要があります。ここで私はもう少しPythonのことをやっていることを再現しようとしています。

完全なコードスニペット(sumc1とcは宣言されていません)を指定していないため、これはテストされていません。私はあなたがやろうとしていることに基づいてこれを書いた。

# Your size16/size17 lists appear to be full of the constant c 
# can use Pythons list replication operation 
sizes16 = [c]*len(dict1) 
sizes17 = [c]*len(dict2) 

# define function for clarity/reduce redundancy 
def get_percentages(l): 
    s = sum(l) 
    percentages = [ round(((float(n)/s)*100),1) for n in l ] # percentages calculation is a great place for list comprehension 
    return percentages 

# can grab the labels directly, rather than in a loop 
labels = dict1.keys() 

percentages1 = get_percentages(dict1.values()) 
percentages2 = get_percentages(dict2.values()) 

# no magic number 5 
for i in range(len(labels)): 
    labels[i] += (', ' + str(percentages[i]) + '%' + ', ' + str(percentages[i + 5]) + '%') 

あなたがしていたことのより良い考えがあれば、その最後の行を削除することができました。

私は注意深く見ていませんが、このコードは余分なデータを1回または2回実行する可能性があるため、少し効率が悪いかもしれません。しかし、はるかに読みやすいIMOです。

1

ここでは、外部ライブラリなしで移動する方法があります。コードが実行される方法には何の問題も言及していませんが、それは美的です(実行する方法に影響を与えると主張できる)。

# Sample data 
d1 = {'a':1.,'b':6.,'c':10.,'d':5.} 
d2 = {'q':10.,'r':60.,'s':100.,'t':50.} 

# List comprehension for each dictionary sum 
sum1 = sum([v for k,v in d1.items()]) 
sum2 = sum([v for k,v in d2.items()]) 

# Using maps and lambda functions to get the distributions of each dictionary 
d1_dist = map(lambda x: round(x/sum1*100, 1), list(d1.values())) 
d2_dist = map(lambda y: round(y/sum2*100, 1), list(d2.values())) 


# Insert your part with the labels here (I really didn't get that part) 

>>> print(d1_dist) 
[4.5, 45.5, 27.3, 22.7] 

をそして、あなたは、これらの新しい配信値に辞書から元のキーに参加したい場合だけ使用します:とにかく、これはきれいに見えます

d1_formatted = dict(zip(list(d1.keys()), d1_dist)) 
>>> print(d1_formatted) 
{'a': 4.5, 'c': 45.5, 'b': 27.3, 'd': 22.7} 
関連する問題