@DSM के पास IMO का सही उत्तर है, लेकिन मैं अपने सामान्यीकरण और प्रश्न के अनुकूलन को साझा करना चाहूंगा: कई कॉलम समूह-द्वारा और कई मान स्तंभों के साथ:
df = pd.DataFrame(
{
'category': ['X', 'X', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
'name': ['A','A', 'B','B','B','B', 'C','C','C'],
'other_value': [10, np.nan, np.nan, 20, 30, 10, 30, np.nan, 30],
'value': [1, np.nan, np.nan, 2, 3, 1, 3, np.nan, 3],
}
)
... देता है ...
category name other_value value
0 X A 10.0 1.0
1 X A NaN NaN
2 X B NaN NaN
3 X B 20.0 2.0
4 X B 30.0 3.0
5 X B 10.0 1.0
6 Y C 30.0 3.0
7 Y C NaN NaN
8 Y C 30.0 3.0
इस सामान्यीकृत मामले में हम categoryऔर के द्वारा समूह बनाना चाहते हैं name, और केवल पर थोपना चाहते हैं value।
इसे निम्नानुसार हल किया जा सकता है:
df['value'] = df.groupby(['category', 'name'])['value']\
.transform(lambda x: x.fillna(x.mean()))
समूह-दर-खंड में कॉलम सूची पर ध्यान दें, और हम valueसमूह-दर के बाद स्तंभ का चयन करें । यह परिवर्तन केवल उस विशेष स्तंभ पर चलाया जाता है। आप इसे अंत तक जोड़ सकते हैं, लेकिन फिर आप इसे सभी स्तंभों के लिए चलाएंगे, लेकिन अंत में सभी माप स्तंभों को निकाल देंगे। एक मानक SQL क्वेरी प्लानर इसे अनुकूलित करने में सक्षम हो सकता है, लेकिन पांडा (0.19.2) ऐसा करने के लिए प्रतीत नहीं होता है।
डेटासेट बढ़ाकर प्रदर्शन परीक्षण ...
big_df = None
for _ in range(10000):
if big_df is None:
big_df = df.copy()
else:
big_df = pd.concat([big_df, df])
df = big_df
... पुष्टि करता है कि इससे गति आनुपातिक बढ़ जाती है कि आपको कितने कॉलम लगाने हैं:
import pandas as pd
from datetime import datetime
def generate_data():
...
t = datetime.now()
df = generate_data()
df['value'] = df.groupby(['category', 'name'])['value']\
.transform(lambda x: x.fillna(x.mean()))
print(datetime.now()-t)
t = datetime.now()
df = generate_data()
df["value"] = df.groupby(['category', 'name'])\
.transform(lambda x: x.fillna(x.mean()))['value']
print(datetime.now()-t)
अंतिम नोट पर आप आगे भी सामान्यीकरण कर सकते हैं यदि आप एक से अधिक कॉलम लगाना चाहते हैं, लेकिन सभी नहीं:
df[['value', 'other_value']] = df.groupby(['category', 'name'])['value', 'other_value']\
.transform(lambda x: x.fillna(x.mean()))
groupbyखंड में शामिल है । याद रखने के लिए बहुत अधिक सामान है, लेकिन आप नियमों को उठाते हैं जैसे "परिवर्तन प्रति समूह संचालन के लिए है जिसे आप मूल फ्रेम की तरह अनुक्रमित करना चाहते हैं" और इसी तरह।