我有一个4列数组:
A=array([[100,1,500,1],
[100,1,501,1],
[101,1,501,1],
[102,2,502,2],
[500,1,100,1],
[100,1,500,1],
[502,2,102,2],
[502,1,102,1]])
我想提取唯一(或第一次出现)的行和行,以便对于行i
,在j
的数组中没有其他行A[i,:]==A[j,[2,1,0,3]]
(或第一次出现)。
因此对于数组A
,我想得到一个类似于:
B=array([[100,1,500,1],
[100,1,501,1],
[101,1,501,1],
[102,2,502,2],
[502,1,102,1]])
感谢您的帮助!
答案 0 :(得分:2)
A[np.unique(np.sort(A,1).view("int, int, int, int"), return_index=True)[1]]
分步骤:
In [385]: A
Out[385]:
array([[100, 1, 500, 1],
[100, 1, 501, 1],
[101, 1, 501, 1],
[102, 2, 502, 2],
[500, 1, 100, 1],
[100, 1, 500, 1],
[502, 2, 102, 2],
[502, 1, 102, 1]])
我们可以简单地通过对每一行进行排序来消除交换第0列和第2列(A[i] = A[j, [2,1,0,3]
)的需要。我们不必担心交换第1列和第3列,因为对于A
中的所有行,我们将第1列等于第3列:A[:, 1] == A[:, 3]
。
In [386]: As = np.sort(A,1)
In [387]: As
Out[387]:
array([[ 1, 1, 100, 500],
[ 1, 1, 100, 501],
[ 1, 1, 101, 501],
[ 2, 2, 102, 502],
[ 1, 1, 100, 500],
[ 1, 1, 100, 500],
[ 2, 2, 102, 502],
[ 1, 1, 102, 502]])
在As
(排序数组)中查找唯一行。将其视为结构化数组,其中每一行都是单个元素(因为np.unique
将首先展平数组)
In [388]: As.view('int, int, int, int')
Out[388]:
array([[(1, 1, 100, 500)],
[(1, 1, 100, 501)],
[(1, 1, 101, 501)],
[(2, 2, 102, 502)],
[(1, 1, 100, 500)],
[(1, 1, 100, 500)],
[(2, 2, 102, 502)],
[(1, 1, 102, 502)]],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8')])
In [389]: u, i = np.unique(As.view('int, int, int, int'), return_index=True)
In [390]: i
Out[390]: array([0, 1, 2, 7, 3])
并使用它们从原始数组As
中获取A
中唯一的行:
In [391]: A[i]
Out[391]:
array([[100, 1, 500, 1],
[100, 1, 501, 1],
[101, 1, 501, 1],
[502, 1, 102, 1],
[102, 2, 502, 2]])
答案 1 :(得分:0)
对于唯一行,您可以使用python集删除重复项。由于np数组(或列表)不可用,您可能必须在选择时将行转换为元组,然后转换回数组:
B = np.array(list(set([tuple(x) for x in A])))
对于问题的第二部分,您需要实现自己的选择循环:
B = []
for row in A:
lrow = list(row)
if lrow not in B and [lrow[2], lrow[1], lrow[0], lrow[3]] not in B:
B.append(lrow)
B = np.array(B)
答案 2 :(得分:0)
我不明白问题的第二部分意味着什么(启动A [i:]的部分)但是作为一个简单的循环你也可以使用
B = []
for data in A:
if data not in B:
B.append(data)
tuple(B)
这将循环通过A,检查它是否已经在B中并附加它。这不是最有效的方法,因为你需要每次循环B,但它很简单明了。
你是否要求数据= [0,1,2,3]不存在像[2,0,1,3]这样的行
如果是这种情况,则添加到if
and [data[2], data[0], data[1], data[3]] not in B
我认为将其设置为树和分支处理可能会有效。也就是说,在A [0]处通过A [1]的值创建分支。然后是A [2]的分支和A [3]处的叶子。在最后的叶子上,如果叶子已经存在则丢弃它。一旦构建了树结构,返回并收集所有分支和叶子到数组结构中,根据定义,它们将是唯一的。在任何情况下,这都需要读取初始列表一次,并且不需要为A中的每一行完全读取B列表。我没有时间弄清楚如何用Python而不是视觉流程图来表达它。也许它可以作为一组词典工作,但我不确定。
{A[0]:{A[1]:{A[2]:{A[3]:True}}}}
不起作用,因为它会覆盖密钥的值。也许每个键和子键的字典列表是可能的,给出一组键A [1]的字典和键A [2]的字典列表
在读取每个条目时,如果在特定列表中找不到A [3],则追加它。如果找到它,则它是重复的。我认为基数将是
的顺序{A[0]:({A[1]:({A[2]:(A[3])})})}
我不知道这个概念是否有效,但需要适当的for循环和附加,并且可能太复杂而无法设置。