Python中基于行输入的条件和
我试图用Python做一个条件和积。简化思路如下:Python中基于行输入的条件和,python,python-3.x,sum,conditional,Python,Python 3.x,Sum,Conditional,我试图用Python做一个条件和积。简化思路如下: A = [1 1 2 3 3 3] B = [0.50 0.25 0.99 0.80 0.70 0.20] 我想把它作为输出 Total1 = 0.50*1 + 0.25*1 Total2 = 0.99*2 Total3 = 0.80*3 + 0.70*3 + 0.20*3 我想用一个。。。如果。。。结构,指定对于a中的给定值,应将B中的所有对应值相加 事实上,这是一个巨大的数据集,所以我必须让脚本能够遍历所有类别 目前,我正在努力将这个想
A = [1 1 2 3 3 3]
B = [0.50 0.25 0.99 0.80 0.70 0.20]
我想把它作为输出
Total1 = 0.50*1 + 0.25*1
Total2 = 0.99*2
Total3 = 0.80*3 + 0.70*3 + 0.20*3
我想用一个。。。如果。。。结构,指定对于a
中的给定值,应将B
中的所有对应值相加
事实上,这是一个巨大的数据集,所以我必须让脚本能够遍历所有类别
目前,我正在努力将这个想法转化为一个合适的Python脚本。
有人能给我指出正确的方向吗?我想你可以用
itertools解决这个问题。groupby
:
import itertools
from operator import itemgetter
results = [group * sum(v[1] for v in values)
for group, values in itertools.groupby(zip(A, B), itemgetter(0))]
这假设
A
中所有相等的数字彼此相邻。如果它们可能没有排序,您可能需要对它们进行排序或使用不同的算法。这似乎非常适合(假设a
中的值是排序的,那么a=[1,1,2,2,1]
可能无法正常工作):
其中打印:
1 0.75
2 1.98
3 5.1
您还可以将其存储在列表中,而不是打印值:
res = []
for key, grp in groupby(zip(A, B), key=lambda x: x[0]):
grp = [i[1] for i in grp]
res.append(key*sum(grp))
print(res)
# [0.75, 1.98, 5.1]
如果第三方软件包可能是您的选择,您还可以使用: 或者直接使用
groupedby
的reduce
参数:
>>> groupedby(zip(A, B), key=itemgetter(0), keep=lambda x: x[0]*x[1], reduce=add)
{1: 0.75, 2: 1.98, 3: 5.1}
免责声明:我是该软件包的作者。我想到了类似的东西。有一个边缘案例我不知道该如何处理,希望可以删除:
In [1]: sums = {}
In [2]: A = [1, 1, 2, 3, 3, 3]
...: B = [0.50, 0.25, 0.99, 0.80, 0.70, 0.20]
In [3]: for count, item in zip(A, B):
...: try:
...: sums[count] += item * count
...: except KeyError:
...: sums[count] = item * count
...:
In [4]: sums
Out[5]: {1: 0.75, 2: 1.98, 3: 5.1}
编辑:
正如注释deafultdict
中所建议的,它可以用来摆脱这个丑陋的try except
块:
In [2]: from collections import defaultdict
In [3]: sum = defaultdict(lambda: 0)
In [4]: sum[1]
Out[4]: 0
In [5]: sum
Out[5]: defaultdict(<function __main__.<lambda>>, {1: 0})
如果您不介意为此使用numpy并假设组已排序,则可以通过以下方式进行操作:
A = [1, 1, 2, 3, 3, 3]
B = [0.50, 0.25, 0.99, 0.80, 0.70, 0.20]
A = np.asarray([1, 1, 2, 3, 3, 3])
B = np.asarray([0.50, 0.25, 0.99, 0.80, 0.70, 0.20])
index = np.full(len(A),True)
index[:-1] = A[1:] != A[:-1]
prods = A*B
#result
res = np.add.reduceat(prods, np.append([0], (np.where(index)[0]+1)[:-1]))
此外,如果您有大的列表,这会真正加快操作速度您能澄清A和B之间的关系吗?当然,一些上下文:我有一个公司名称(行)的excel文件,列中有1°“类型”=要应用的2°百分比=B我需要获得每种公司类型的百分比总和。希望这有帮助!如果没有,开枪!这种情况下的产品是什么?似乎您只是想要一个sum。您可以使用初始化为0的
defaultdict
来避免try-except
块,而不是使用lambda:0
只需使用int
。这是因为int()还有一个问题,A中的值未排序。。例如:A=[1 1 2 3 1 4 2 1]B中的值按以下顺序与A中的值匹配。因此,如果我对A排序,B就不再匹配了?在这种情况下,您可以对邮政编码进行排序。与只使用zip(A,B)
不同,您必须使用sorted(zip(A,B),key=lambda x:x[0])
(基于A排序而不丢失B的相应值)。这只适用于itertools.groupby
但是-对于iteration\u实用程序.groupedby
它不需要排序。谢谢,工作非常好!)对于10个不同的B柱,是否有这样做的选项?还是只运行程序10次更好?这取决于不同的B
列的存储方式。通常你可以把它放在所有不同的列中的循环中:
。但是,您可以问另一个问题,包括B
s是如何存储的(在哪个容器中):)在评论中回答这个问题有点太难了。好的,谢谢!完整性:本答案中提到的方法部分基于此。
In [2]: from collections import defaultdict
In [3]: sum = defaultdict(lambda: 0)
In [4]: sum[1]
Out[4]: 0
In [5]: sum
Out[5]: defaultdict(<function __main__.<lambda>>, {1: 0})
In [6]: sums = defaultdict(int)
In [7]: A = [1, 1, 2, 3, 3, 3]
...: B = [0.50, 0.25, 0.99, 0.80, 0.70, 0.20]
In [8]: for count, item in zip(A, B):
...: sums[count] += count * item
...:
In [9]: sums
Out[9]: defaultdict(int, {1: 0.75, 2: 1.98, 3: 5.1})
A = [1, 1, 2, 3, 3, 3]
B = [0.50, 0.25, 0.99, 0.80, 0.70, 0.20]
A = np.asarray([1, 1, 2, 3, 3, 3])
B = np.asarray([0.50, 0.25, 0.99, 0.80, 0.70, 0.20])
index = np.full(len(A),True)
index[:-1] = A[1:] != A[:-1]
prods = A*B
#result
res = np.add.reduceat(prods, np.append([0], (np.where(index)[0]+1)[:-1]))