Python-循环的组合

Python-循环的组合,python,performance,dictionary,for-loop,Python,Performance,Dictionary,For Loop,我有两个分别来自2016年和2017年的数据字典,它们有相同的5个键。我想计算每个键的值占其字典中值之和的百分比,然后将每个键的两个百分比连接到一个标签。我已经在下面成功地做到了,但是我的方法需要大量的循环,而且看起来有些笨拙。我正在寻找压缩或重写代码的方法,以提高效率 UsersPerCountry, UsersPerPlatform, UsersPerPlatform2016, UsersPerPlatform2017 = Analytics.UsersPerCountryOrPlatfor

我有两个分别来自2016年和2017年的数据字典,它们有相同的5个键。我想计算每个键的值占其字典中值之和的百分比,然后将每个键的两个百分比连接到一个标签。我已经在下面成功地做到了,但是我的方法需要大量的循环,而且看起来有些笨拙。我正在寻找压缩或重写代码的方法,以提高效率

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的矢量化机制在两行中执行相同的计算。ie
df=pd.DataFrame(dict1)
df2=pd.DataFrame(dict2)
,甚至将它们组合成一个
df=pd.concat([df1,df2],key=[20162017])
。请发布完整的代码片段。e、 g.
sumc1
c
从未声明过……您是否考虑过使用
Pandas
?您可以将每个字典放入一个
pd.DataFrame
,并使用panda的矢量化机制在两行中执行相同的计算。ie
df=pd.DataFrame(dict1)
df2=pd.DataFrame(dict2)
,甚至将它们组合成一个
df=pd.concat([df1,df2],key=[20162017])