从键值对列表中创建矩阵

时间:2013-06-18 16:05:22

标签: python numpy

我有一个numpy数组列表,其中包含两个字符串的名称 - 值对列表。每个名称和值都可以在列表中找到多次,我想将其转换为二进制矩阵。

列表示值,而行表示键/名称,当字段设置为1时,它表示特定的名称值对。

E.g

我有

A : aa
A : bb
A : cc
B : bb
C : aa

我希望将其转换为

     aa bb cc 
 A    1  1  1
 B    0  1  0 
 C    1  0  0 

我有一些代码可以做到这一点,但我想知道是否有一个更简单/开箱即用的方式来使用numpy或其他库。

到目前为止,这是我的代码:

resources = Set(result[:,1])
resourcesDict = {}
i = 0 
for r in resources:   
    resourcesDict[r] = i
    i = i + 1

clients = Set(result[:,0])
clientsDict = {}
i = 0 
for c in clients:    
    clientsDict[c] = i
    i = i + 1

arr = np.zeros((len(clientsDict),len(resourcesDict)), dtype = 'bool')
for line in result[:,0:2]: 
    arr[clientsDict[line[0]],resourcesDict[line[1]]] = True

结果如下

array([["a","aa"],["a","bb"],..]

4 个答案:

答案 0 :(得分:1)

你可能有像

这样的东西
m_dict = {'A': ['aa', 'bb', 'cc'], 'B': ['bb'], 'C': ['aa']}

我会这样:

res = {}
for k, v in m_dict.items():
    res[k] = defaultdict(int)
    for col in v:
        res[k][v] = 1

修改

根据你的格式,它可能更符合以下方面:

m_array = [['A', 'aa'], ['A', 'bb'], ['A', 'cc'], ['B', 'bb'], ['C', 'aa']]

res = defaultdict(lambda: defaultdict(int))
for k, v in m_array:
    res[k][v] = 1

两者都给出了:

>>> res['A']['aa']
1
>>> res['B']['aa']
0

答案 1 :(得分:1)

这是np.unique的工作。目前尚不清楚您的数据是什么格式,但您需要获得两个1-D阵列,一个带有键,另一个带有值,例如:

kvp = np.array([['A', 'aa'], ['A', 'bb'], ['A', 'cc'],
                ['B', 'bb'], ['C', 'aa']])

keys, values = kvp.T

rows, row_idx = np.unique(keys, return_inverse=True)
cols, col_idx = np.unique(values, return_inverse=True)

out = np.zeros((len(rows), len(cols)), dtype=np.int)
out[row_idx, col_idx] += 1

>>> out
array([[1, 1, 1],
       [0, 1, 0],
       [1, 0, 0]])
>>> rows
array(['A', 'B', 'C'], 
      dtype='|S2')
>>> cols
array(['aa', 'bb', 'cc'], 
      dtype='|S2')

如果您没有重复的键值对,此代码将正常工作。如果有重复,我建议滥用scipy的稀疏模块:

import scipy.sparse as sps

kvp = np.array([['A', 'aa'], ['A', 'bb'], ['A', 'cc'],
                ['B', 'bb'], ['C', 'aa'], ['A', 'bb']])

keys, values = kvp.T

rows, row_idx = np.unique(keys, return_inverse=True)
cols, col_idx = np.unique(values, return_inverse=True)

out = sps.coo_matrix((np.ones_like(row_idx), (row_idx, col_idx))).A

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

答案 2 :(得分:0)

d = {'A': ['aa', 'bb', 'cc'], 'C': ['aa'], 'B': ['bb']}
rows = 'ABC'
cols = ('aa', 'bb', 'cc')
print '   ', ' '.join(cols)
for row in rows:
    print row, ' ',
    for col in cols:
            print ' 1' if col in d.get(row) else ' 0',
    print

>>>     aa bb cc
>>> A    1  1  1
>>> B    0  1  0
>>> C    1  0  0

答案 3 :(得分:0)

我觉得使用Pandas.DataFrame.pivot是最好的方法

>>> df = pd.DataFrame({'foo': ['one','one','one','two','two','two'],
                       'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
                       'baz': [1, 2, 3, 4, 5, 6]})
>>> df
    foo   bar  baz
0   one   A    1
1   one   B    2
2   one   C    3
3   two   A    4
4   two   B    5
5   two   C    6

或者 你可以使用

加载你的配对列表
>>> df = pd.read_csv('ratings.csv')

然后

>>> df.pivot(index='foo', columns='bar', values='baz')
     A   B   C
one  1   2   3
two  4   5   6