gpt4 book ai didi

wolfram-mathematica - 如何从矩阵中选择特定列中具有唯一条目的行?

转载 作者:行者123 更新时间:2023-12-04 08:00:09 31 4
gpt4 key购买 nike

我尝试使用功能性方式解决此问题,但没有取得太大成功。

假设有一个列表列表,需要只选取其中在特定位置具有唯一条目的列表。

例如,假设有一个矩阵,我们只想选择第一列中具有唯一元素的行。

下面是一个例子:

输入:

list= {{ 1,2}, {1,3},{4,5}}

我希望输出是
list={{1,2},{4,5}}

删除哪一个“行”并不重要,第一个可以,但任何一个都可以。

我尝试了 Select、DeleteCases、DeleteDuplicates、Union 和其他一些东西,但无法让它工作。我不知道如何告诉 Mathematica 只寻找“唯一”元素。 Union 接近,但它适用于完整列表。即我不知道为标准写什么,如
DeleteDuplicates[list, <now what?> ]

作为引用,这就是我在 Matlab 中执行上述操作的方式:
EDU>> A=[1 2;1 3;4 5]

A =
1 2
1 3
4 5

EDU>> [B,I,J]=unique(A(:,1));
EDU>> A(I,:)

ans =
1 3
4 5

谢谢

最佳答案

这是一种方法:

DeleteDuplicates[list, First@#1 === First@#2 &]

编辑

请注意,下面的时间和讨论基于 M7

经过一些反射(reflection),我发现了一个解决方案,对于大列表来说,它(至少)要快几个数量级,有时要快两个数量级,对于这种特殊情况(可能更好的说法是下面的解决方案会有不同的计算复杂度):
Clear[delDupBy];
delDupBy[nested_List, n_Integer] :=
Module[{parts = nested[[All, n]], ord, unpos},
ord = Ordering[parts];
unpos = Most@Accumulate@Prepend[Map[Length, Split@parts[[ord]]], 1];
nested[[Sort@ord[[unpos]]]]];

基准:
In[406]:= 
largeList = RandomInteger[{1,15},{50000,2}];

In[407]:= delDupBy[largeList,1]//Timing
Out[407]= {0.016,{{13,4},{12,1},{1,6},{6,13},{10,12},{7,15},{8,14},
{14,4},{4,1},{11,9},{5,11},{15,4},{2,7},{3,2},{9,12}}}

In[408]:= DeleteDuplicates[largeList,First@#1===First@#2&]//Timing
Out[408]= {1.265,{{13,4},{12,1},{1,6},{6,13},{10,12},{7,15},{8,14},{14,4},
{4,1},{11,9},{5,11},{15,4},{2,7},{3,2},{9,12}}}

这一点特别值得注意,因为 DeleteDuplicates是一个内置函数。我可以盲目猜测 DeleteDuplicates用户定义测试使用二次时间成对比较算法,而 delDupByn*log n在列表的大小。

我认为这是一个重要的教训:我们应该注意 Union 等内置函数。 , Sort , DeleteDuplicates等使用自定义测试时。我在 this 中更广泛地讨论了它Mathgroup 线程,其中还有其他有见地的回复。

最后,让我提一下,这个问题在 here 之前已经被问过(强调效率)。 .我将在这里重现我为第一个(或通常为 n -th)元素是正整数(泛化到任意整数很简单)的情况给出的解决方案:
Clear[sparseArrayElements];
sparseArrayElements[HoldPattern[SparseArray[u___]]] := {u}[[4, 3]]

Clear[deleteDuplicatesBy];
Options[deleteDuplicatesBy] = {Ordered -> True, Threshold -> 1000000};
deleteDuplicatesBy[data_List, n_Integer, opts___?OptionQ] :=
Module[{fdata = data[[All, n]], parr,
rlen = Range[Length[data], 1, -1],
preserveOrder = Ordered /. Flatten[{opts}] /. Options[deleteDuplicatesBy],
threshold = Threshold /. Flatten[{opts}] /. Options[deleteDuplicatesBy], dim},
dim = Max[fdata];
parr = If[dim < threshold, Table[0, {dim}], SparseArray[{}, dim, 0]];
parr[[fdata[[rlen]]]] = rlen;
parr = sparseArrayElements@If[dim < threshold, SparseArray@parr, parr];
data[[If[preserveOrder, Sort@parr, parr]]]
];

这种工作方式是使用第一个(或通常是 n -th)个元素作为某些
我们预先分配了一个巨大的表,利用它们是正整数)。在某些情况下,这可以给我们带来疯狂的表现。观察:
In[423]:= hugeList = RandomInteger[{1,1000},{500000,2}];

In[424]:= delDupBy[hugeList,1]//Short//Timing
Out[424]= {0.219,{{153,549},{887,328},{731,825},<<994>>,{986,150},{92,581},{988,147}}}

In[430]:= deleteDuplicatesBy[hugeList,1]//Short//Timing
Out[430]= {0.032,{{153,549},{887,328},{731,825},<<994>>,{986,150},{92,581},{988,147}}}

关于wolfram-mathematica - 如何从矩阵中选择特定列中具有唯一条目的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7254923/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com