मेरे पास पंडों का फॉर्म का डाटाफ्रेम है:
id start_time sequence_no value
0 71 2018-10-17 20:12:43+00:00 114428 3
1 71 2018-10-17 20:12:43+00:00 114429 3
2 71 2018-10-17 20:12:43+00:00 114431 79
3 71 2019-11-06 00:51:14+00:00 216009 100
4 71 2019-11-06 00:51:14+00:00 216011 150
5 71 2019-11-06 00:51:14+00:00 216013 180
6 92 2019-12-01 00:51:14+00:00 114430 19
7 92 2019-12-01 00:51:14+00:00 114433 79
8 92 2019-12-01 00:51:14+00:00 114434 100
मैं जो करने की कोशिश कर रहा हूं वह sequence_no प्रति लापता id/ start_timeकॉम्बो में भर गया है । उदाहरण के लिए, id/ की start_timeजोड़ी, 71और 2018-10-17 20:12:43+00:00गायब है अनुक्रम_नो 114430. प्रत्येक जोड़े गए लापता अनुक्रम_न के लिए, मुझे लापता valueकॉलम मान को औसत / प्रक्षेपित करने की भी आवश्यकता है । तो, उपरोक्त डेटा का अंतिम प्रसंस्करण इस तरह दिखाई देगा:
id start_time sequence_no value
0 71 2018-10-17 20:12:43+00:00 114428 3
1 71 2018-10-17 20:12:43+00:00 114429 3
2 71 2018-10-17 20:12:43+00:00 114430 41 **
3 71 2018-10-17 20:12:43+00:00 114431 79
4 71 2019-11-06 00:51:14+00:00 216009 100
5 71 2019-11-06 00:51:14+00:00 216010 125 **
6 71 2019-11-06 00:51:14+00:00 216011 150
7 71 2019-11-06 00:51:14+00:00 216012 165 **
8 71 2019-11-06 00:51:14+00:00 216013 180
9 92 2019-12-01 00:51:14+00:00 114430 19
10 92 2019-12-01 00:51:14+00:00 114431 39 **
11 92 2019-12-01 00:51:14+00:00 114432 59 **
12 92 2019-12-01 00:51:14+00:00 114433 79
13 92 2019-12-01 00:51:14+00:00 114434 100
( **आसान पठनीयता के लिए नई सम्मिलित पंक्तियों के दाईं ओर जोड़ा गया)
ऐसा करने के लिए मेरा मूल समाधान डेटा की एक बड़ी तालिका पर पायथन छोरों पर बहुत अधिक निर्भर था, इसलिए यह चमकदार और पांडा को चमकने के लिए आदर्श स्थान की तरह लग रहा था। पंडों की तरह एसओ जवाब पर झुकना: संख्यात्मक अंतराल को भरने के लिए पंक्तियां बनाएं , मैं साथ आया:
import pandas as pd
import numpy as np
# Generate dummy data
df = pd.DataFrame([
(71, '2018-10-17 20:12:43+00:00', 114428, 3),
(71, '2018-10-17 20:12:43+00:00', 114429, 3),
(71, '2018-10-17 20:12:43+00:00', 114431, 79),
(71, '2019-11-06 00:51:14+00:00', 216009, 100),
(71, '2019-11-06 00:51:14+00:00', 216011, 150),
(71, '2019-11-06 00:51:14+00:00', 216013, 180),
(92, '2019-12-01 00:51:14+00:00', 114430, 19),
(92, '2019-12-01 00:51:14+00:00', 114433, 79),
(92, '2019-12-01 00:51:14+00:00', 114434, 100),
], columns=['id', 'start_time', 'sequence_no', 'value'])
# create a new DataFrame with the min/max `sequence_no` values for each `id`/`start_time` pairing
by_start = df.groupby(['start_time', 'id'])
ranges = by_start.agg(
sequence_min=('sequence_no', np.min), sequence_max=('sequence_no', np.max)
)
reset = ranges.reset_index()
mins = reset['sequence_min']
maxes = reset['sequence_max']
# Use those min/max values to generate a sequence with ALL values in that range
expanded = pd.DataFrame(dict(
start_time=reset['start_time'].repeat(maxes - mins + 1),
id=reset['id'].repeat(maxes - mins + 1),
sequence_no=np.concatenate([np.arange(mins, maxes + 1) for mins, maxes in zip(mins, maxes)])
))
# Use the above generated DataFrame as an index to generate the missing rows, then interpolate
expanded_index = pd.MultiIndex.from_frame(expanded)
df.set_index(
['start_time', 'id', 'sequence_no']
).reindex(expanded_index).interpolate()
आउटपुट सही है, लेकिन यह लगभग उसी गति से चलता है जैसे मेरे बहुत सारे पायथन-लूप समाधान। मुझे यकीन है कि ऐसे स्थान हैं जहां मैं कुछ कदम काट सकता हूं, लेकिन मेरे परीक्षण का सबसे धीमा हिस्सा प्रतीत होता है reindex। यह देखते हुए कि वास्तविक विश्व डेटा में लगभग एक लाख पंक्तियाँ होती हैं (अक्सर संचालित होती हैं), क्या मैंने जो लिखा है उस पर कुछ प्रदर्शन लाभ प्राप्त करने के लिए कोई स्पष्ट तरीके हैं? किसी भी तरह से मैं इस परिवर्तन को गति दे सकता हूं?
अपडेट 9/12/2019
विस्तारित डेटाफ्रेम के मूल निर्माण के साथ इस उत्तर से मर्ज समाधान को संयोजित करना , जब तक कि पर्याप्त बड़े डेटासेट पर परीक्षण नहीं किया जाता है, तब तक सबसे तेज़ परिणाम प्राप्त होता है:
import pandas as pd
import numpy as np
# Generate dummy data
df = pd.DataFrame([
(71, '2018-10-17 20:12:43+00:00', 114428, 3),
(71, '2018-10-17 20:12:43+00:00', 114429, 3),
(71, '2018-10-17 20:12:43+00:00', 114431, 79),
(71, '2019-11-06 00:51:14+00:00', 216009, 100),
(71, '2019-11-06 00:51:14+00:00', 216011, 150),
(71, '2019-11-06 00:51:14+00:00', 216013, 180),
(92, '2019-12-01 00:51:14+00:00', 114430, 19),
(92, '2019-12-01 00:51:14+00:00', 114433, 79),
(92, '2019-12-01 00:51:14+00:00', 114434, 100),
], columns=['id', 'start_time', 'sequence_no', 'value'])
# create a ranges df with groupby and agg
ranges = df.groupby(['start_time', 'id'])['sequence_no'].agg([
('sequence_min', np.min), ('sequence_max', np.max)
])
reset = ranges.reset_index()
mins = reset['sequence_min']
maxes = reset['sequence_max']
# Use those min/max values to generate a sequence with ALL values in that range
expanded = pd.DataFrame(dict(
start_time=reset['start_time'].repeat(maxes - mins + 1),
id=reset['id'].repeat(maxes - mins + 1),
sequence_no=np.concatenate([np.arange(mins, maxes + 1) for mins, maxes in zip(mins, maxes)])
))
# merge expanded and df
merge = expanded.merge(df, on=['start_time', 'id', 'sequence_no'], how='left')
# interpolate and assign values
merge['value'] = merge['value'].interpolate()
mergeकी तुलना में काफी तेज हैreindex, लेकिन यह पता चला है किexplodeबड़े डेटा सेट पर बहुत धीमी है। विस्तारित डेटासेट के मूल निर्माण के साथ अपने मर्ज को जोड़ते समय, हम अब तक का सबसे तेज़ कार्यान्वयन प्राप्त करते हैं (प्रश्न के लिए 9/12/2019 अपडेट देखें)