2025, Sep 25 07:31
Polars में एक ही select से स्केलर mean और centered कॉलम
Polars में एक ही expression प्लान से स्केलर mean और centered कॉलम बनाएं: broadcasting की हकीकत, implode से कुशल लेआउट, पूरी तरह eager मोड की जरूरत नहीं।
Polars में किसी कॉलम को सेंटर करते हुए साथ में उसका स्केलर mean निकालना दिखने में आसान है, लेकिन एक व्यावहारिक सवाल उठता है: जब एक परिणाम स्केलर हो और दूसरा कॉलम, तब expressions से ही कैसे काम लें, eager मोड की राह पर गए बिना, और मेमोरी लेआउट को कुशल कैसे रखें?
पुनरुत्पादन मामला: उसी expression ग्राफ से स्केलर + कॉलम
सेटअप न्यूनतम है। हम एक कॉलम का mean निकालते हैं और केवल expressions के जरिए उसी कॉलम का centered संस्करण बनाते हैं।
import polars as pl
import numpy as np
frame = pl.DataFrame({"probe": np.array([0., 1, 2, 3, 4])})
avg_expr = pl.col("probe").mean().alias("avg")
res_avg = frame.select(avg_expr)
shifted_expr = pl.col("probe") - avg_expr
res_shifted = frame.select(shifted_expr)
स्वाभाविक रूप से, दोनों को एक साथ select करने का मन होता है। डिस्प्ले स्केलर mean को ऐसे दिखाएगा मानो वह सभी पंक्तियों में फैलाया गया हो—यह broadcasting जैसा लगता है और स्टोरेज व्यवहार को लेकर भ्रम पैदा कर सकता है।
असल में हो क्या रहा है
Polars में ScalarColumn नाम की अवधारणा है, जो स्केलर मान रख सकती है। आउटपुट में जो आप broadcasting जैसा देखते हैं, वह अपने आप यह नहीं बताता कि हर पंक्ति के लिए कॉपी बन रही है। हालांकि यह पक्का आश्वासन नहीं है—कुछ स्थितियों में कॉपी सचमुच हो सकती है।
यदि आप चाहते हैं कि दृश्य रूपरेखा वास्तविक मेमोरी लेआउट को दर्शाए—यानी एक स्केलर और एक गैर‑स्केलर, बिना पंक्ति‑दर‑पंक्ति दोहराव के—तो आप गैर‑स्केलर परिणाम को प्रस्तुत करने का तरीका बदल सकते हैं।
समाधान: implode के साथ गैर‑स्केलर को स्पष्ट करें
दोनों परिणामों को साथ रखते हुए, एक स्केलर के बगल में एक संग्रह (collection) की धारणा बनाए रखने के लिए गैर‑स्केलर expression पर implode लगाएँ। इससे एक‑पंक्ति वाला DataFrame मिलता है जिसमें एक स्केलर और एक सूची होती है, और डिस्प्ले इच्छित लेआउट से मेल खाता है।
out = frame.select(
    pl.col("probe").mean().alias("avg"),
    (pl.col("probe") - pl.col("probe").mean()).implode().alias("centered")
)
नतीजे का schema एक f64 स्केलर और centered मानों के लिए list[f64] दिखाता है—दोनों expressions के जरिए, बिना eager चरण के।
यह क्यों मायने रखता है
Polars में expressions पर काम करते हुए अक्सर एक ही select में स्केलर aggregation और कॉलम‑स्तरीय रूपांतरण साथ आते हैं। स्केलर कैसे निरूपित होते हैं और डिस्प्ले का मेमोरी लेआउट से क्या संबंध है—यह समझ लेना स्टोरेज ओवरहेड को लेकर गलत अनुमान से बचाता है। implode का इस्तेमाल आउटपुट को आपकी मंशा के अनुरूप करता है: एक ही पास में बना एक स्केलर मान और उसके साथ एक सघन, वेक्टर‑सदृश फील्ड।
मुख्य बातें
यदि आपको एक ही expression प्लान से स्केलर और व्युत्पन्न कॉलम दोनों चाहिए, तो याद रखें कि स्केलर डिस्प्ले में broadcast हुआ दिख सकता है—भले ही अंदरूनी तौर पर हमेशा कॉपी न बन रही हो। आउटपुट में एक स्केलर के साथ एक ही संग्रह दिखाना हो, तो गैर‑स्केलर expression को implode करें और सब कुछ expression पाइपलाइन में रखें। जहाँ यह पैटर्न आपके काम में फिट न बैठे, वहाँ स्केलर को eager तरीके से निकालकर आगे बढ़ना भी एक व्यवहार्य विकल्प है, यद्यपि वह हमेशा उतना सामान्यीकृत नहीं होता।
यह लेख StackOverflow पर प्रश्न पर आधारित है, जिसे Felix Benning ने पूछा था, और Dean MacGregor के उत्तर पर।