【问题标题】:What's the most pythonic way to load a matrix in ijv/coo/triplet format?以 ijv/coo/triplet 格式加载矩阵的最 Pythonic 方式是什么?
【发布时间】:2015-08-04 14:54:18
【问题描述】:

我的输入文件是 ijv/coo/triplet 格式,带有字符串列名,例如:

Apple,Google,1
Apple,Banana,5
Microsoft,Orange,2

应该产生这个 2x3 矩阵:

[[1,5,0], [0,0,2]]

我可以通过将列名放入字典并创建一个 scipy 稀疏 coo_matrix 并将该字典映射到 ID 来手动读取它。最后我想在 scipy sparse 或 pandas 数据框中得到它。

有没有更多的pythonic方式来做到这一点? Pandas 只能读取 csv,有scipy.io,但它们也没有 coo 格式。因此,如果没有库,将它放入scipy.coo_matrixpandas.DataFrame 的最pythonic 方式是什么?

【问题讨论】:

  • 一个 coo 矩阵应该有对应于坐标的列/行。你的坐标是多少?例如, (Apple,Google ) 是否对应一些值为 1 的 x,y ?
  • "(Apple,Google) 是否对应一些值为 1 的 x,y" 是的。

标签: python pandas scipy scikit-learn


【解决方案1】:

您需要定义从行/列名称到某些索引的明确映射(“Apple”是“0”还是“1”并不重要,只是它由一个数字表示,因此这赢了' 不完全符合您的结果,但这应该没关系)。在此示例中,'info.txt' 包含

Apple,Google,1
Apple,Banana,5
Microsoft,Orange,2

这是实现坐标矩阵的一种方法:

import numpy as np
from scipy.sparse import coo_matrix

input = np.loadtxt( 'info.txt', delimiter=',' , dtype=str)
rows,cols,data = input.T
map_rows = { val:ind for ind,val in enumerate( np.unique(rows) ) }
map_cols = { val:ind for ind,val in enumerate( np.unique(cols) ) }
result   = coo_matrix( (data.astype(float),( [map_rows[x] for x in rows], [map_cols[x] for x in cols]) ) )    

现在你有了映射和结果

print map_rows
#{'Apple': 0, 'Microsoft': 1}
print map_cols
#{'Banana': 0, 'Google': 1, 'Orange': 2}
print result.toarray()
#array([[ 5.,  1.,  0.],
#       [ 0.,  0.,  2.]])

【讨论】:

  • 谢谢@dermen,我喜欢你创建映射的方式(这绝对是我以前的pythonic)。不过,它仍然感觉很冗长。我想我们可以定义def idmap(l): u = np.unique(l) im = { u[x]:x for x in range( u.shape[0] ) } return map( lambda x: im[x], l ) 来节省三行。
  • Id 假设您希望保留映射字典以供以后使用,您可能会因函数调用而松散。但这取决于代码的总体目的和范围。您可以使用 enumerate 来消除使用 u_rowsu_cols 变量的需要。此外,您可以直接在coo_matrix 的参数中应用映射以节省空间,但这有点乱。
  • 我决定使用函数并将映射与映射字典一起返回。非常感谢您的回答!我希望这个功能会在 sklearn/pandas 中被采用,但同时我想它并没有变得更容易:) 我会接受你的回答。
【解决方案2】:

您可以为此使用 csv:

matrix = []
with open('input_file', 'rb') as csvfile:
     input_reader = csv.reader(csvfile, delimiter=',')
     for row in input_reader:
         matrix.append([row[0], row[1], row[2]])

然后你会在matrix

[['Apple', 'Google', '1'], ['Apple', 'Banana', '5'], ['Microsoft', 'Orange', '2']]

如果你想要一个 numpy 矩阵,我相信根据 documentation 这应该可以工作:

nm_matrix = np.matrix(matrix)

【讨论】:

  • 谢谢。我最初的问题不够清楚,我的目标是将它变成一个对象,然后我可以在 scikit-learn/pandas 中使用它。比如一个numpy矩阵、DataFrame或者coo_matrix。
  • 我开始明白,提出一个明确的问题很难 :) 不幸的是,这并没有产生所需的输出。是的,得到一个 numpy 矩阵,但格式有点不同:rowName,columnName,value。因此,所需的输出将是一个 numpy 矩阵:[[1,5,0],[0,0,2]]。我会将这个添加到示例中。
  • 很抱歉,我不明白您是如何从您的输入中获得[[1,5,0],[0,0,2]] 的。
  • 值 1 在名称/id Apple 的行和名称/id Google 的列中。行 ID Apple 列 ID 香蕉的单元格包含值 5。等
  • 我还是不明白,抱歉。程序应该如何知道什么是什么?算法是什么?也许其他人可以帮助你。
【解决方案3】:

[line.split(",") for line in open(input_file)] 会起作用吗?

该代码将从文件中读取每一行,分成以逗号分隔的行,并将结果收集到一个列表中。

【讨论】:

  • 很遗憾没有,总体目标是把它变成numpy/coo_matrix/DataFrame数据结构。
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多