我有一个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"],..]
答案 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