Python-循环的组合
我有两个分别来自2016年和2017年的数据字典,它们有相同的5个键。我想计算每个键的值占其字典中值之和的百分比,然后将每个键的两个百分比连接到一个标签。我已经在下面成功地做到了,但是我的方法需要大量的循环,而且看起来有些笨拙。我正在寻找压缩或重写代码的方法,以提高效率Python-循环的组合,python,performance,dictionary,for-loop,Python,Performance,Dictionary,For Loop,我有两个分别来自2016年和2017年的数据字典,它们有相同的5个键。我想计算每个键的值占其字典中值之和的百分比,然后将每个键的两个百分比连接到一个标签。我已经在下面成功地做到了,但是我的方法需要大量的循环,而且看起来有些笨拙。我正在寻找压缩或重写代码的方法,以提高效率 UsersPerCountry, UsersPerPlatform, UsersPerPlatform2016, UsersPerPlatform2017 = Analytics.UsersPerCountryOrPlatfor
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]) + '%')
这是标签的外观:
编辑:我现在添加了变量声明。我认为关于将所有变量设置为空列表或0的散列行就足够了。您可以使用Panda的数据帧类来简化事情。我有点不确定您的百分比是如何计算的,因此可能需要计算一点,否则,请尝试以下方法:
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
您可以使用Panda的数据帧类来简化事情。我有点不确定您的百分比是如何计算的,因此可能需要计算一点,否则,请尝试以下方法:
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
没有熊猫:
您应该利用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]) + '%')
如果我对你所做的有更好的了解,最后一行可以清理干净
我还没有仔细研究过,但是这段代码可能会在数据上额外运行一到两次,所以效率可能会低一些。但是,在我看来,它更容易阅读。没有熊猫:
您应该利用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]) + '%')
如果我对你所做的有更好的了解,最后一行可以清理干净
我还没有仔细研究过,但是这段代码可能会在数据上额外运行一到两次,所以效率可能会低一些。然而,在我看来,它更具可读性。这里有一种不用外部库的方法。您没有提到代码运行方式中的任何问题,只提到它的美学(有人可能会认为这会影响代码的运行方式)。无论如何,这看起来很干净:
# 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}
这里有一种不用外部库的方法。您没有提到代码运行方式中的任何问题,只提到它的美学(有人可能会认为这会影响代码的运行方式)。无论如何,这看起来很干净:
# 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}
请发布完整的代码片段。e、 g.
sumc1
和c
从未声明过……您是否考虑过使用Pandas
?您可以将每个字典放入一个pd.DataFrame
,并使用panda的矢量化机制在两行中执行相同的计算。iedf=pd.DataFrame(dict1)
和df2=pd.DataFrame(dict2)
,甚至将它们组合成一个df=pd.concat([df1,df2],key=[20162017])
。请发布完整的代码片段。e、 g.sumc1
和c
从未声明过……您是否考虑过使用Pandas
?您可以将每个字典放入一个pd.DataFrame
,并使用panda的矢量化机制在两行中执行相同的计算。iedf=pd.DataFrame(dict1)
和df2=pd.DataFrame(dict2)
,甚至将它们组合成一个df=pd.concat([df1,df2],key=[20162017])
。