Python 用np列出理解。在哪里比较两个数组并组合它们,第一个条目是相等的
我想要一个数组“set1”,它包含在数组“a”的前四行中,如果一行的第一个值/元素与“a”和“d”相同,那么根据“d”的第二个值,会有另一个区别:Python 用np列出理解。在哪里比较两个数组并组合它们,第一个条目是相等的,python,arrays,numpy,Python,Arrays,Numpy,我想要一个数组“set1”,它包含在数组“a”的前四行中,如果一行的第一个值/元素与“a”和“d”相同,那么根据“d”的第二个值,会有另一个区别: 如果“d”行中的第二个值为=1->a中“d”的第三个值 在行的第四个元素的“set1”中写入行 如果“d”行中的第二个值是=2->a中“d”的第三个值 行在该行的第五个元素的“set1”中写入 如果“d”行中的第二个值是=3->a中“d”的第三个值 在行的第六个元素的“set1”中写入行 “a”第一个位置的一个值在“d”中出现0-3次 到目前为止
- 如果“d”行中的第二个值为=1->a中“d”的第三个值 在行的第四个元素的“set1”中写入行
- 如果“d”行中的第二个值是=2->a中“d”的第三个值 行在该行的第五个元素的“set1”中写入
- 如果“d”行中的第二个值是=3->a中“d”的第三个值 在行的第六个元素的“set1”中写入行 “a”第一个位置的一个值在“d”中出现0-3次
只有当第一个元素的相同编号只出现一次时,我的代码才起作用(在这种情况下,仅正确显示集合1“6 61 62 64 0 44 0”的最后一行)。在所有其他情况下,不归档所需的输出。 例如,将显示第五行:
[5 51 52 54 0 0 0]
而不是想要的
[5 51 52 54 3 0 1]
有没有更“蟒蛇式”的方法?比较第一个元素,并根据上面的规则(1-->第四个元素,等等)组合它们
[编辑]更改数字以避免将ID与索引混淆
d
的前两列是set1
中的索引,您希望在稍加更正后将值放置在d
的第三列。从这里开始,它就像使用我在评论中链接的索引模式一样简单
完整示例:
a=np.array((
[1,2,3,4],
[2,22,23,24],
[3,31,32,34],
[4,41,42,44],
[5,51,52,54],
[6,61,62,64]))
d=np.array((
[2,3,5],
[4,1,4],
[2,1,2],
[5,3,1],
[6,2,44],
[5,1,3],
[1,3,55],
[1,1,6]))
# allocate the result array
m, n = a.shape
res = np.zeros((m, n+3))
res[:m, :n] = a
# do the work
i, j, values = d.T
res[i-1, j+3] = values
以致
>>> res
array([[ 1., 2., 3., 4., 6., 0., 55.],
[ 2., 22., 23., 24., 2., 0., 5.],
[ 3., 31., 32., 34., 0., 0., 0.],
[ 4., 41., 42., 44., 4., 0., 0.],
[ 5., 51., 52., 54., 3., 0., 1.],
[ 6., 61., 62., 64., 0., 44., 0.]])
如果
d
的第一列不是索引。。。
在d
的第一列不是索引的一般情况下,您需要在a
中查找d[:,0]
的每个条目的位置。渐近实现这一点的最快方法是使用哈希表,但实际上,实现这一点的足够快的方法是使用np.searchsorted
:
a=np.array((
[5,2,3,4],
[3,22,23,24],
[2,31,32,34],
[1,41,42,44],
[4,51,52,54],
[8,61,62,64]))
d=np.array((
[2,3,5],
[4,1,4],
[2,1,2],
[5,3,1],
[8,2,44],
[5,1,3],
[1,3,55],
[1,1,6]))
# allocate the result array
m, n = a.shape
res = np.zeros((m, n+3))
res[:m, :n] = a
# do the work
i, j, values = d.T
ids = a[:, 0]
sort_ix = np.argsort(ids)
search_ix = np.searchsorted(ids, i, sorter=sort_ix)
id_map = sort_ix[search_ix]
res[id_map, j+3] = values
以致
>>> res
array([[ 5., 2., 3., 4., 3., 0., 1.],
[ 3., 22., 23., 24., 0., 0., 0.],
[ 2., 31., 32., 34., 2., 0., 5.],
[ 1., 41., 42., 44., 6., 0., 55.],
[ 4., 51., 52., 54., 4., 0., 0.],
[ 8., 61., 62., 64., 0., 44., 0.]])
注意:如果d[0,:]
具有连续整数1,…,n
,但不一定按顺序排列,则可以避免排序,只使用直接查找表。将上述注释后的位替换为:
# do the work
i, j, values = d.T
ids = a[:, 0]
id_map = np.zeros_like(ids)
id_map[ids-1] = np.arange(len(ids))
res[id_map[i-1], j+3] = values
我在遵循您的示例时遇到一些问题,当我运行您的代码时,结果似乎与所需结果的描述不匹配。尽管如此,似乎您应该能够使用numpy中的基本索引模式(请参阅:)完成您想要做的事情。另一方面,如果这是你的实际数据,你可能需要考虑一个不同的表示,因为有大量的冗余和重复的值。我试图使问题更加清楚。如果
d
的第一列不是索引而是ID,那么d
中行的第一个条目必须等于set1
的第一个条目,你现在能更好地理解它吗。这只是我的一个例子,其中的条目碰巧等于标记。对于第二个任务,它是一个指示,这是正确的。感谢您在代码和完善我的问题方面的帮助!谢谢你的完整解释!你会推荐什么方法来真正“更多地思考”列表理解和索引?因为我刚刚开始使用python和numpy,仍然很欣赏解决方案的简单性,现在可以回顾每一步,但我不能完全依靠自己去实现。我尝试过使用np.searchsorted
,但首先没有使用np.argsort
。请注意:a
是连续的,但不是以1
开头,但是带有413001
和d
的内容不是连续的,只是a
的子集
# do the work
i, j, values = d.T
ids = a[:, 0]
id_map = np.zeros_like(ids)
id_map[ids-1] = np.arange(len(ids))
res[id_map[i-1], j+3] = values