数据真的像这样。
1,000-00-000,GRABBUS,OCTOPUS ,, M,26-Nev-12,,05 FRENCH TOAST ROAD ,, VACANT,ZA,1867,(001)111-1011,(002)111-1000 ,,
我必须让它看起来很傻,因为它包含专有信息。
这是使用clojure-csv创建矢量矢量之前的样子。
我使用解析后的数字来简化,但它们并没有减少到一个值。我想从clojure-csv解析数据中挑选某些列并创建一个较小的csv行。
请对我的道歉感到抱歉。
如何确定何时使用reduce或改为使用pmap?
前一段时间,我的博客上有关于减少的评论。特别是评论说减少一般不能并行化,但map(pmap)可能是。
何时使用或不使用reduce会产生影响,例如 以下是否有所作为?
谢谢。
(def csv-row [1 2 3 4 5 6 7 8 9])
(def col-nums [0 1 4])
(defn reduce-csv-rowX
"Accepts a csv-row and a list of columns to extract, and
reduces the csv-row to the selected list using a list comprehension."
[csv-row col-nums]
(for [col-num col-nums
:let [part-row (nth csv-row col-num nil)]]
part-row))
(defn reduce-csv-row
"Accepts a csv-row and a list of columns to extract, and
reduces the csv-row to the selected list."
[csv-row col-nums]
(reduce
(fn [out-csv-row col-num]
(let [out-val (nth csv-row col-num nil)]
(if-not (nil? out-val)
(conj out-csv-row out-val))))
[]
col-nums))
(defn reduce-csv-row “接受csv-row和要提取的列列表,以及 将csv-row缩减为所选列表。“ [csv-row col-nums] (降低 (fn [out-csv-row col-num] (让[out-val(nth csv-row col-num nil)] (conj out-csv-row out-val))) [] COL-NUMS))
答案 0 :(得分:5)
通常,您希望使用可以编写最简单代码的函数。这通常意味着最具体的功能。在这种情况下,您可以将操作视为将列列表转换为列中行的值列表。这相当于map
,因此您可能希望使用map
。您可以使用reduce
进行撰写,但在这种情况下,您在调用map
时重新实施reduce
,因此这可能是错误的方法。
但是,有时reduce
是正确的选择。如果您尝试将列表“缩减”为任意值,map
对您来说根本无济于事。在这种情况下,reduce
就是您想要的,并且由于您的操作不可并行化,reduce
也不可并行化。
如果您对reduce
代码不理想的原因更感兴趣,如果我们抽象出特定于应用程序的代码,我们就会得到
(reduce
(fn [out-list current-val]
(let [out-val (f current-val)]
(if-not (nil? out-val)
(conj out-list out-val))))
[]
col-nums)
一个复杂因素是if-not
电话。目前,它的马车 - 如果out-val
永远为零,你将扔掉你到目前为止所发现的所有东西并重新开始((if-not (nil? out-val) (conj out-list out-val))
的回报是nil
out-val
1}}为零,因此nil
将用作下一个out-list
)。由于你的其他实现没有任何nil检查,并且这个nil检查是错误的(因此可能从未使用过),我假设它可以被忽略。此时,您的代码是
(reduce
(fn [out-list current-val]
(let [out-val (f current-val)]
(conj out-list out-val)))
[]
col-nums)
这是map
的完全有效(尽管是非懒惰)实现。使用对map
的实际调用可以让您消除所有与您的特定问题实际无关的代码,而是专注于您实际尝试的操作。你可以通过查看ivant的解决方案来看到它的效果。
答案 1 :(得分:3)
使用地图的解决方案可能如下所示:
(defn reduce-csv-rowM [csv-row col-nums]
(pmap (fn [pos] (nth csv-row pos)) col-nums))
它是平凡可并行化的,如果csv-row是一个向量,则nth非常快,所以没关系。
所以在你的情况下,我认为地图解决方案是最好的,因为它比其他两个更容易理解,并且也可以更快。
一般情况下,map和reduce不可互换,事实上它们非常有用(比如谷歌的map-reduce技术)。
答案 2 :(得分:1)
Resuce和map是一个很好的削减,它们经常被一起使用, map-reduce现在是一个常见的行业术语。通常,map用于将数据转换为可以聚合的形式,并将聚合数据减少为单个答案。如果还原功能是可交换的, reduce可以并行化。例如,使用+
进行并行缩减就可以了,而使用/
则效果不佳。
map
reduce
答案 3 :(得分:1)
您还可以使用select-keys,它以不同的格式返回响应:
(select-keys [1 2 3 4 5 6 7 8 9] [0 1 4])
;==> {4 5, 1 2, 0 1}
即从键到值的映射。它看起来更适合地图,但也适用于其他seq。
你也可以看一下clojure.set / project,它就像select-keys(实际上是在内部使用它),但对于整个表,而不是只有一行。