2012-04-30 42 views
4

我有一個大的多列數據文件的選擇,但對於這個問題,它可以簡化爲:映射一個列表上的第二列表

data = {{"a", 2000}, {"a", 2010}, {"b", 1999}, {"b", 2004}, {"b", 
2006}, {"c", 2012}, {"c", 2014}}; 

然後我有一個項目清單,我想從數據中提取的年份,例如:

selectedList = {"b", "c"}; 

我可以通過選擇[],然後通過迭代selectedList做到這一點:

Table[ 
     Select[data, #[[1]] == selectedList[[i]] &][[All, 2]], 

     {i, 1, Length[selectedList]} ] 

但是我想使用Map,它應該比Table快。我可以這樣做:

func[dat_, x_] := Select[dat, #[[1]] == x &][[All, 2]] 

然後:

func[data, #] & /@ selectedList 

我正在尋找一種更優雅的方式一步到位做到這一點,最好是直接映射選擇到selectedList

回答

3

我會用地圖與案例:

data = {{"a", 2000}, {"a", 2010}, {"b", 1999}, {"b", 2004}, 
    {"b", 2006}, {"c", 2012}, {"c", 2014}}; 
selectedList = {"b", "c"}; 

Map[Part[Cases[data, {#, _}], All, 2] &, selectedList] 

{{1999年,2004年,2006年},{2012,2014}}

但是,如果您真的想使用Select,您可以按如下所示進行操作。功能用於避免混淆匿名插槽。我已經建立了功能逐漸加以說明: -

Select[data, First[#] == "b" &] (* Basic start *) 

{{ 「B」,1999},{ 「B」,2004},{ 「B」,2006年}}

Select[data, Function[x, First[x] == "b"]] (* Implement with Function *) 

{{ 「b」,1999},{ 「b」,2004},{ 「b」,2006年}}

Part[Select[data, Function[x, First[x] == "b"]], All, 2] 

{1999年,2004年,2006年}

Map[Part[Select[data, 
    Function[x, First[x] == #]], All, 2] &, selectedList] 

{{1999年,2004年,2006年},{2012,2014}}

+0

謝謝!正是我在找的案例或選擇,但不是表格:-) – BlueMac

3

另一種方法是使用Position

Map[Function[x, data[[Position[data, x][[All, 1]], 2]]], selectedList] 

(* {{1999, 2004, 2006}, {2012, 2014}} *) 
2

對於變化在這裏是另一個基於選擇:

Last[#\[Transpose]] & /@ (Select[data, Function[x, First[x] == #1]] &) 
/@ selectedList 
6
Cases[data, {#, x_} :> x] & /@ selectedList 
+0

非常優雅的解決方案。 –

+1

+1,但是我通常會將它封裝在Block [{x},...]中,以防萬一'x'被定義在其他地方。儘管它破壞了簡潔性。 –

+0

這確實很高雅,但我真正的數據文件來自excel,並且是一個多列文件,第10列中的日期 - 這將起作用:-)'Cases [data,{#,_,_,_,_,_, _,_,_,x _,___}:> x]&/ @ selectedList' – BlueMac

1

我會用:

Reap[Sow[#2, #] & @@@ data, selectedList][[2, All, 1]] 
{{1999, 2004, 2006}, {2012, 2014}} 

這很容易適應其他結構,例如,第十列:Sow[#10, #]

對於大型數據集和較長的selectedList,這將比Cases更快,因爲數據未針對每個選擇元素重新掃描。

例子:

data = {RandomChoice[CharacterRange["a", "z"], 50000], 
     RandomInteger[100000, 50000]}\[Transpose]; 

selectedList = RandomSample @ CharacterRange["a", "z"]; 

Reap[Sow[#2, #] & @@@ data, selectedList][[2, All, 1]]; //AbsoluteTiming 

Cases[data, {#, x_} :> x] & /@ selectedList;   //AbsoluteTiming 
{0.0210012, Null} 

{0.1010057, Null} 
相關問題