计算数组列表的计数百分比

时间:2016-07-21 12:49:23

标签: python arrays list numpy

简单的问题,但我似乎无法让它发挥作用。我想计算一个数字在数组列表中出现的百分比,并相应地输出这个百分比。 我有一个数组列表,如下所示:

import numpy as np

# Create some data   
listvalues = []

arr1 = np.array([0, 0, 2])
arr2 = np.array([1, 1, 2, 2])
arr3 = np.array([0, 2, 2])

listvalues.append(arr1)
listvalues.append(arr2)
listvalues.append(arr3)

listvalues
>[array([0, 0, 2]), array([1, 1, 2, 2]), array([0, 2, 2])]

现在我使用集合来计算事件,这会返回集合列表.Counter:

import collections 

counter = []
for i in xrange(len(listvalues)):
    counter.append(collections.Counter(listvalues[i]))

counter
>[Counter({0: 2, 2: 1}), Counter({1: 2, 2: 2}), Counter({0: 1, 2: 2})]

我正在寻找的结果是一个包含3列的数组,表示行的值0到2和len(列表值)。每个单元格应填充数组中出现的值的百分比:

# Result
66.66    0      33.33
0        50     50
33.33    0      66.66

因此0在阵列1中出现66.66%,在阵列2中出现0%,在阵列3中出现33.33%,依此类推......

实现这一目标的最佳方法是什么? 非常感谢!

5 个答案:

答案 0 :(得分:2)

numpy_indexed包有一个实用程序函数,称为count_table,可以用来有效地解决你的问题:

import numpy_indexed as npi
arrs = [arr1, arr2, arr3]
idx = [np.ones(len(a))*i for i, a in enumerate(arrs)]
(rows, cols), table = npi.count_table(np.concatenate(idx), np.concatenate(arrs))
table = table / table.sum(axis=1, keepdims=True)
print(table * 100)

答案 1 :(得分:2)

您可以获取所有值的列表,然后简单地遍历各个数组以获得百分比:

values = set([y for row in listvalues for y in row]) print [[(a==x).sum()*100.0/len(a) for x in values] for a in listvalues]

答案 2 :(得分:1)

这是一种方法 -

# Get lengths of each element in input list
lens = np.array([len(item) for item in listvalues])

# Form group ID array to ID elements in flattened listvalues
ID_arr = np.repeat(np.arange(len(lens)),lens)

# Extract all values & considering each row as an indexing perform counting
vals = np.concatenate(listvalues)
out_shp = [ID_arr.max()+1,vals.max()+1]
counts = np.bincount(ID_arr*out_shp[1] + vals)

# Finally get the percentages with dividing by group counts
out = 100*np.true_divide(counts.reshape(out_shp),lens[:,None])

在输入列表中使用另外的第四个数组运行示例 -

In [316]: listvalues
Out[316]: [array([0, 0, 2]),array([1, 1, 2, 2]),array([0, 2, 2]),array([4, 0, 1])]

In [317]: print out
[[ 66.66666667   0.          33.33333333   0.           0.        ]
 [  0.          50.          50.           0.           0.        ]
 [ 33.33333333   0.          66.66666667   0.           0.        ]
 [ 33.33333333  33.33333333   0.           0.          33.33333333]]

答案 3 :(得分:0)

您可以使用以下代码创建包含百分比的列表:

percentage_list = [((counter[i].get(j) if counter[i].get(j) else 0)*10000)//len(listvalues[i])/100.0 for i in range(len(listvalues)) for j in range(3)]

之后,从该列表中创建一个np数组:

results = np.array(percentage_list)

重塑它,以便我们取得好成绩:

results = results.reshape(3,3)

这应该可以让你得到你想要的东西 这很可能效率不高,而不是最好的方法,但它具有工作的优点。

如果您有任何疑问,请不要犹豫。

答案 4 :(得分:0)

我想使用functional-paradigm来解决这个问题。例如:

>>> import numpy as np
>>> import pprint
>>> 
>>> arr1 = np.array([0, 0, 2])
>>> arr2 = np.array([1, 1, 2, 2])
>>> arr3 = np.array([0, 2, 2])
>>> 
>>> arrays = (arr1, arr2, arr3)
>>> 
>>> u = np.unique(np.hstack(arrays))
>>> 
>>> result = [[1.0 * c.get(uk, 0) / l
...            for l, c in ((len(arr), dict(zip(*np.unique(arr, return_counts=True))))
...            for arr in arrays)] for uk in u]
>>> 
>>> pprint.pprint(result)
[[0.6666666666666666, 0.0, 0.3333333333333333],
 [0.0, 0.5, 0.0],
 [0.3333333333333333, 0.5, 0.6666666666666666]]