4

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

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

例如

我有

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

4 回答 4

2

我觉得使用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
于 2017-02-18T00:04:32.540 回答
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
于 2013-06-18T16:27:40.800 回答
1

这是一份工作np.unique。目前尚不清楚您的数据采用什么格式,但您需要获得两个一维数组,一个带有键,另一个带有值,例如:

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 的 sparse 模块:

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]])
于 2013-06-18T23:55:00.193 回答
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
于 2013-06-18T16:37:55.237 回答