I am using a Beam pipeline to count the frequencies of phone numbers for streaming data. I'm using sliding windows which repeat every 5 mins with total period of 15 mins, so as expected, for some inputs I am getting multiple outputs when the input falls in multiple windows.
After calculating the number of occurrences, I would like to find the mean value for the input feature. The inputs are tuples like:
('phone_number', '123')
('phone_number', '456')
('phone_number', '456')
('phone_number', '456')
The first part of pipeline is to count the frequency of each number:
| 'window' >> beam.WindowInto(window.SlidingWindows(900, 300))
| 'pair_with_one' >> beam.Map(lambda x: (x, 1))
| 'count_occurences' >> beam.combiners.Count.PerKey()
This correctly my calculation works correctly and I can count the frequency of each number, getting 3 results as there are 3 sliding windows in each period (in our case 2 of the 456 calls were in the same window and the third was in a different one):
(('phone_number', '123'), 1)
(('phone_number', '123'), 1)
(('phone_number', '123'), 1)
(('phone_number', '456'), 2)
(('phone_number', '456'), 2)
(('phone_number', '456'), 2)
(('phone_number', '456'), 1)
(('phone_number', '456'), 1)
(('phone_number', '456'), 1)
Now, I'd like to find the mean for each phone number over all the window values calculated, i.e.:
(('phone_number', '123'), 1.0)
(('phone_number', '456'), 1.5)
The next step in my pipeline is
| 'Find Means' >> beam.combiners.Mean.PerKey()
But this just gives me:
(('phone_number', '123'), 1.0)
(('phone_number', '123'), 1.0)
(('phone_number', '123'), 1.0)
(('phone_number', '456'), 2.0)
(('phone_number', '456'), 2.0)
(('phone_number', '456'), 2.0)
(('phone_number', '456'), 1.0)
(('phone_number', '456'), 1.0)
(('phone_number', '456'), 1.0)
Is there any way of doing another beam.combiners calculation on the results of a previous one?