用Python在2D数组中累加值
我有一个numpy 2D数组,如下所示用Python在2D数组中累加值,python,arrays,python-2.7,numpy,Python,Arrays,Python 2.7,Numpy,我有一个numpy 2D数组,如下所示 gona = array([['a1', 3], ['a2', 5], ['a3', 1], ['a3', 2], ['a3', 1], ['a1', 7]]) 此数组有2列 我要做的是创建一个包含两列的数组。第1列的“行”中应包含“a1”、“a2”、“a3”值,第2列应包含这些对应值的总和 new_gona = array([['a1', 10], ['a2', 5], ['a3', 4]]) 这里,对应的值如下所示 'a1' : 3 + 7 = 1
gona = array([['a1', 3], ['a2', 5], ['a3', 1], ['a3', 2], ['a3', 1], ['a1', 7]])
此数组有2列
我要做的是创建一个包含两列的数组。第1列的“行”中应包含“a1”、“a2”、“a3”值,第2列应包含这些对应值的总和
new_gona = array([['a1', 10], ['a2', 5], ['a3', 4]])
这里,对应的值如下所示
'a1' : 3 + 7 = 10
'a2' : 5
'a3' : 1 + 2 + 1 = 4
实现这一点的简单方法是什么?您必须围绕gona编写一个循环,并将(a1)存储为dictionary对象中的键。当然,应该添加值,您必须围绕gona编写一个循环,并将(a1)存储为dictionary对象中的键。当然,价值应该被增加
from collections import defaultdict
from operator import itemgetter
sums = defaultdict(int)
for key, value in gona:
sums[key] += value
new_gona = sorted(sums.iteritems(), key=itemgetter(0))
欺骗
作弊?使用熊猫及其索引魔法:
import pandas as pd
import numpy as np
gona = np.array([['a1', 3], ['a2', 5], ['a3', 1],
['a3', 2], ['a3', 1], ['a1', 7]])
# Create series where second items are data and first items are index
series = pd.Series(gona[:,1],gona[:,0],dtype=np.float)
# Compute sums across index
sums = series.sum(level=0)
# Construct new array in the format you want
new_gona = np.array(zip(sums.index,sums.values))
new_gona
# out[]:
# array([['a1', '10.0'],
# ['a2', '5.0'],
# ['a3', '4.0']],
# dtype='|S4')
另外值得注意的是,
np.array
s只能保存一种数据类型。因此,需要通过指定dtype=np.float
来纠正字符串和数字类型的混合。如果需要,您可以使用np.int
。使用熊猫及其索引魔法:
import pandas as pd
import numpy as np
gona = np.array([['a1', 3], ['a2', 5], ['a3', 1],
['a3', 2], ['a3', 1], ['a1', 7]])
# Create series where second items are data and first items are index
series = pd.Series(gona[:,1],gona[:,0],dtype=np.float)
# Compute sums across index
sums = series.sum(level=0)
# Construct new array in the format you want
new_gona = np.array(zip(sums.index,sums.values))
new_gona
# out[]:
# array([['a1', '10.0'],
# ['a2', '5.0'],
# ['a3', '4.0']],
# dtype='|S4')
另外值得注意的是,np.array
s只能保存一种数据类型。因此,需要通过指定dtype=np.float
来纠正字符串和数字类型的混合。如果需要,您可以使用np.int
。仅限numpy的解决方案:
>>> labels, indices = np.unique(gona[:, 0], return_inverse=True)
>>> sums = np.bincount(indices, weights=gona[:, 1].astype(np.float))
>>> new_gona = np.column_stack((labels, sums))
>>> new_gona
array([['a1', '10'],
['a2', '5.'],
['a3', '4.']],
dtype='|S2')
仅限numpy的解决方案:
>>> labels, indices = np.unique(gona[:, 0], return_inverse=True)
>>> sums = np.bincount(indices, weights=gona[:, 1].astype(np.float))
>>> new_gona = np.column_stack((labels, sums))
>>> new_gona
array([['a1', '10'],
['a2', '5.'],
['a3', '4.']],
dtype='|S2')
然后,列表理解将非常简单:
def fst(x): return x[0]
[(a, sum([int(m[1]) for m in gona if a == m[0]])) for a in set(map(fst, gona)) ]
这是基本的Python。没有涉及图书馆。第一个函数的定义仅在末尾的
map
中避免lambda表达式。不过,前面提到的熊猫和NumPy解决方案似乎都很有趣+两人各得1分 那么,列表理解将非常简单:
def fst(x): return x[0]
[(a, sum([int(m[1]) for m in gona if a == m[0]])) for a in set(map(fst, gona)) ]
这是基本的Python。没有涉及图书馆。第一个函数的定义仅在末尾的
map
中避免lambda表达式。不过,前面提到的熊猫和NumPy解决方案似乎都很有趣+两人各得1分 我记得上次出现这个问题时,我看到了一个有效的解决方案,但我不记得是什么。也许有更好的搜索技巧的人可以找到它。注意:运行您发布的代码会生成一个数据类型数组“|S2”
。这意味着整数存储为字符串,而不是作为int32
或其他合理的数据类型。这可能是个问题。我记得上次出现这个问题时,我看到了熊猫的有效解决方案,但我不记得是什么。也许有更好的搜索技巧的人可以找到它。注意:运行您发布的代码会生成一个数据类型数组“|S2”
。这意味着整数存储为字符串,而不是作为int32
或其他合理的数据类型。这可能是一个问题。请发表评论,询问了提供的解决方案。没有代码,只有逻辑解释注释,请提供解决方案。没有代码,只有逻辑解释