2025, Oct 21 04:31

NumPy मास्क से buildup/run-off के लिए N बाय 3N−2 array बनाना

इस गाइड में NumPy मास्क के साथ तिर्यक विंडो बनाकर buildup–peak–run-off पैटर्न का N×(3N−2) array तैयार करें। कोड, उदाहरण और Pandas DataFrame आउटपुट।

जब भारों का अनुक्रम A1, A2, ..., AN एक ऐसे आयताकार ढांचे में जोड़ना हो जो पहले बढ़ता है, फिर चरम पर पहुँचता है और बाद में घटता जाता है—साथ ही भारों के चक्र से गुजरता है—तो तर्क आसानी से उलझ सकता है। इसे बनाने का सरल तरीका है NumPy के मास्क इस्तेमाल करना, जो तिर्यकों (diagonals) को एक तय पैटर्न में भरते हैं, और फिर उन्हें दिए गए भारों के साथ समेकित कर देते हैं। जरूरत हो तो अंतिम परिणाम को Pandas DataFrame में बदला जा सकता है।

हमें क्या उत्पन्न करना है

संख्या N के लिए A1..AN से N पंक्तियों और 3N−2 स्तंभों वाला एक array बनाएं। हर पंक्ति एक शिफ्ट किए गए आरंभ बिंदु से मेल खाती है, और स्तंभ उस संचयन को दर्शाते हैं जो क्रम में आगे बढ़ते मान जोड़कर पहले बढ़ता है, फिर शुरुआती मान हटाने से घटता है—जबकि अनुक्रम A के मानों पर चक्रीय रूप से घूमता रहता है। उदाहरण के तौर पर, N = 3 होने पर यह मिलता है:

    0   1   2   3   4   5   6
0   1.0 3.0 6.0 5.0 3.0 0.0 0.0
1   0.0 2.0 5.0 6.0 4.0 1.0 0.0
2   0.0 0.0 3.0 4.0 6.0 3.0 2.0

यह पैटर्न, उदाहरण के लिए, पुनर्बीमा में वर्ष के दौरान जुड़ने वाले जोखिमों के संदर्भ में उपयोगी है, जहाँ A1..AN लिखित व्यवसाय के मासिक हिस्सों का प्रतिनिधित्व कर सकते हैं, और हर पंक्ति दिखाती है कि लिखित राशियाँ कैसे जमा होती हैं और फिर अनुबंधों के रन-ऑफ के साथ घटती जाती हैं।

कोड उदाहरण: मूल पैटर्न

मुख्य बात यह है कि हर शिफ्ट के लिए 1 का एक ऐसा मास्क बनाया जाए जो बताए कि वजन कहाँ योगदान देता है, फिर इन मास्कों को गुणा कर जोड़ लिया जाए। किसी दिए गए शिफ्ट पर मास्क में 1 के दो आयताकार ब्लॉक होते हैं: पहला वर्तमान शिफ्ट तक नीचे की ओर फैलता है, दूसरा शेष पंक्तियों में आगे बढ़ता है। इन मास्कों का न्यूनतम निर्माण इस प्रकार है:

import numpy as np

dim = 3

for ofs in range(dim):  # ofs stands for the current shift
    mask = np.zeros((dim, 3*dim - 2))

    left = dim + ofs
    right = 2*dim + ofs

    mask[:ofs+1, ofs:left] = 1
    mask[ofs+1:, left:right] = 1

dim = 3 होने पर, ये मास्क ऐसे दिखते हैं:

[[1. 1. 1. 0. 0. 0. 0.]
 [0. 0. 0. 1. 1. 1. 0.]
 [0. 0. 0. 1. 1. 1. 0.]]

[[0. 1. 1. 1. 0. 0. 0.]
 [0. 1. 1. 1. 0. 0. 0.]
 [0. 0. 0. 0. 1. 1. 1.]]

[[0. 0. 1. 1. 1. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0.]]

यह क्यों काम करता है

हर मास्क तिर्यक-सदृश योगदान खिड़की को एन्कोड करता है। 1 का पहला ब्लॉक वर्तमान शिफ्ट के बराबर स्तंभ से शुरू होकर वर्तमान पंक्ति तक नीचे भरता है, जिससे buildup बनता है। दूसरा ब्लॉक स्तंभ dim + shift से शुरू होकर शेष पंक्तियों में चलता है, जिससे run-off बनता है। इन मास्कों को, उनके संबंधित भार से स्केल कर, जोड़ने पर वह मैट्रिक्स मिलता है जहाँ प्रत्येक स्तंभ लगातार भारों के एक विशेष संयोजन का प्रतिनिधित्व करता है, और बीच के क्षेत्र में N लगातार पदों के अधिकतम योग दिखाई देते हैं। आकार N बाय 3N−2 होता है, जो buildup–peak–decay की पूरी अवधि से मेल खाता है।

किसी भी N के लिए पूर्ण समाधान

यह पूरी प्रक्रिया है जो हर मास्क को उसके भार से गुणा कर परिणाम को समेकित करती है। पहले NumPy array बनता है, फिर उसे Pandas DataFrame में बदला जाता है.

import numpy as np
import pandas as pd

dim = 3
weights = [1, 2, 3]
accum = np.zeros((dim, 3*dim - 2))

for ofs in range(dim):
    mask = np.zeros((dim, 3*dim - 2))
    left = dim + ofs
    right = 2*dim + ofs
    mask[:ofs+1, ofs:left] = 1
    mask[ofs+1:, left:right] = 1
    accum += weights[ofs] * mask

pd.DataFrame(accum)

dim = 3 और weights [1, 2, 3] के लिए प्राप्त DataFrame यह है:

    0   1   2   3   4   5   6
0   1.0 3.0 6.0 5.0 3.0 0.0 0.0
1   0.0 2.0 5.0 6.0 4.0 1.0 0.0
2   0.0 0.0 3.0 4.0 6.0 3.0 2.0

इसे समझकर अपनाना क्यों उपयोगी है

यह निर्माण ठीक उसी तरह काम करता है जैसे ऐसे शेड्यूल व्यवहार में चलते हैं—उदाहरण के लिए, पुनर्बीमा में वर्ष के दौरान जुड़ने वाले जोखिम। यह तरीका NumPy की समानरूपी संख्यात्मक प्रकृति और सरल इंडेक्सिंग का फायदा उठाता है, जो यहां स्वाभाविक रूप से उपयुक्त है। यदि आप तिर्यकों में सोचना पसंद करते हैं, तो NumPy के उपकरण, जैसे diag, तिर्यक संरचनाएँ बनाने के लिए उपलब्ध हैं। बार-बार पद जोड़‑घटा कर स्तंभों को बदलने की तुलना में यह अधिक मजबूत है, और बिना किसी खास केस के स्वाभाविक रूप से किसी भी N तक सामान्यीकृत हो जाता है।

मुख्य बातें

मास्क के जरिए buildup और run-off को मॉडल करें और दिए गए भारों के साथ समेकित करें। NumPy में N बाय 3N−2 का array बनाएं, और प्रस्तुति के लिए उसे DataFrame में बदलें। शिफ्टेड विंडो को तिर्यकों के रूप में सोचें और गणना का काम उन्हीं मास्कों को करने दें। इससे तर्क साफ रहता है और अलग‑अलग N पर बिना विशेष मामलों के आसानी से स्केल किया जा सकता है।

यह लेख StackOverflow पर प्रश्न (लेखक: Matta) और Jokilos के उत्तर पर आधारित है।