我有一个
形式的数据集user_id, date, other_columns
1, 2017-03-10, ...
2, 2017-03-10, ...
3, 2017-03-10, ...
...
我需要执行以下操作:对于数据集中的每一行,我想生成一个新行,该行将包含当前行以及对应于不同用户的同一天的N行的随机子集如下:
row, other_rows
{'user_id': 1, 'date': '2017-03-10', ...}, [{'user_id': 2,...},...]
{'user_id': 2, 'date': '2017-03-10', ...}, [{'user_id': 1,...},...]
...
我已将其实现如下,但在云上执行时,对于大型数据集来说非常慢。
dataset
| 'map-to-date' >> beam.Map(lambda x: (x['date'], x))
| 'group-by-date' >> beam.GroupByKey()
| 'generate-output' >> beam.ParDo(GenerateOutputRows())
其中GenerateOutputRows
定义为:
class GenerateOutputRows(beam.DoFn):
def process(self, element):
(date, rows) = element
for r in rows:
other_users_rows = list(filter(lambda x: x['user_id'] != r['user_id'],
rows))
yield (r, random.sample(other_users_rows, N))
你能想到另一种更有效的方法来获得理想的结果吗?
答案 0 :(得分:0)
除非你能提供一些简化的假设,否则我不会立即在算法上看到更有效的方法,例如:
一般来说,这是一个算法问题,而不是Cloud Dataflow / Apache Beam问题,因为代码的瓶颈是GenerateOutputRows中的O(rows.size()^ 2)循环,而Beam不能自动加快;我建议前往http://cstheory.stackexchange.com寻求有关更高效算法的建议。