我有一个大的多列数据文件,但对于这个问题,它可以简化如下:
data = {{"a", 2000}, {"a", 2010}, {"b", 1999}, {"b", 2004}, {"b",
2006}, {"c", 2012}, {"c", 2014}};
然后我有一个项目列表,我想从数据中提取年份值,例如:
selectedList = {"b", "c"};
我可以通过使用Select []然后迭代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
我正在寻找一种更优雅的方法,一步完成,最好是直接选择选择列表
答案 0 :(得分:6)
Cases[data, {#, x_} :> x] & /@ selectedList
答案 1 :(得分: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}}
答案 2 :(得分:3)
另一种方法是使用Position
:
Map[Function[x, data[[Position[data, x][[All, 1]], 2]]], selectedList]
(* {{1999, 2004, 2006}, {2012, 2014}} *)
答案 3 :(得分:2)
这里的变化是另一个基于选择:
Last[#\[Transpose]] & /@ (Select[data, Function[x, First[x] == #1]] & )
/@ selectedList
答案 4 :(得分: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}