这是帖子How to extract rows from an numpy array based on the content?的相对问题,我使用以下代码根据列中的内容拆分行:
np.split(sorted_a,np.unique(sorted_a[:,1],return_index=True)[1][1:])
代码工作正常,但后来我尝试将代码拆分为其他情况(如下所示),我发现可能存在错误的结果(如CASE#1所示)。
CASE#1
[[2748309, 246211, 1],
[2748309, 246211, 2],
[2747481, 246201, 54]]
OUTPUT#1
[]
[[2748309, 246211, 1],
[2748309, 246211, 2],
[2747481, 246201, 54]]
the result I want
[[2748309, 246211, 1],
[2748309, 246211, 2]]
[[2747481, 246201, 54]]
我认为代码可能只在数字较少的情况下成功分割行,数字较少,我不知道如何解决上述情况#1中显示的问题。所以在这篇文章中,我有两个相对较小的问题:
1。如何拆分数字更大的行? (如案例#1所示)?
2。如何处理(拆分)两种情况下的数据,包括第二列中具有相同元素的#1行,但第一列中的第1行和第2行中的元素相同,但第二列中的元素不同? (也就是说,python可以同时考虑第一列和第二列中的内容来区分行吗?)
随时给我建议,谢谢。
更新#1
ravel_multi_index
函数可以使用整数数组处理这种任务,但是如何处理包含float的数组?
答案 0 :(得分:1)
这是一种将每行中的元素对作为索引元组的方法 -
# Convert to linear index equivalents
lidx = np.ravel_multi_index(arr[:,:2].T,arr[:,:2].max(0)+1)
# Get sorted indices of lidx. Using those get shifting indices.
# Split along sorted input array along axis=0 using those.
sidx = lidx.argsort()
out = np.split(arr[sidx],np.unique(lidx[sidx],return_index=1)[1][1:])
示例运行 -
In [34]: arr
Out[34]:
array([[2, 7, 5],
[3, 4, 6],
[2, 3, 5],
[2, 7, 7],
[4, 4, 7],
[3, 4, 6],
[2, 8, 5]])
In [35]: out
Out[35]:
[array([[2, 3, 5]]), array([[2, 7, 5],
[2, 7, 7]]), array([[2, 8, 5]]), array([[3, 4, 6],
[3, 4, 6]]), array([[4, 4, 7]])]
有关将元素组转换为索引元组的详细信息,请参阅this post
。
答案 1 :(得分:0)
numpy_indexed包(免责声明:我是其作者)包含有效执行这些类型操作的功能:
import numpy_indexed as npi
npi.group_by(a[:, :2]).split(a)
它具有不错的测试覆盖率,所以如果它在你看似简单的测试用例上绊倒,我会感到惊讶。
答案 2 :(得分:0)
如果我将该分割线直接应用于您的数组,我会得到您的结果,一个空数组加上原始
In [136]: np.split(a,np.unique(a[:,1],return_index=True)[1][1:])
Out[136]:
[array([], shape=(0, 3), dtype=int32),
array([[2748309, 246211, 1],
[2748309, 246211, 2],
[2747481, 246201, 54]])]
但是,如果我首先按照链接答案中的指定对第二列上的数组进行排序,我得到了所需的答案 - 切换了2个数组
In [141]: sorted_a=a[np.argsort(a[:,1])]
In [142]: sorted_a
Out[142]:
array([[2747481, 246201, 54],
[2748309, 246211, 1],
[2748309, 246211, 2]])
In [143]: np.split(sorted_a,np.unique(sorted_a[:,1],return_index=True)[1][1:])
Out[143]:
[array([[2747481, 246201, 54]]),
array([[2748309, 246211, 1],
[2748309, 246211, 2]])]