एक समय सीमा डेटाफ़्रेम के लिए पंक्तियों को कैसे जोड़ा जाए?
मैं एक प्रोग्राम लिख रहा हूं जो एक टाइमस्टाइल एक्सेल फाइल में डेटाफ्रेम में लोड होगा, फिर मैं कुछ बुनियादी गणनाओं का उपयोग करके कई नए कॉलम बनाता हूं। मेरा कार्यक्रम कभी-कभी एक्सेल फाइलों में पढ़ा जा रहा है जो कुछ रिकॉर्ड के लिए महीनों से गायब हैं। इसलिए नीचे दिए गए उदाहरण में मेरे पास दो अलग-अलग स्टोर के लिए मासिक बिक्री डेटा है। स्टोर अलग-अलग महीनों के दौरान खुलते हैं, इसलिए उनकी पहली महीने की समाप्ति तिथि अलग-अलग होगी। लेकिन दोनों में 9/30/2020 तक महीने का अंत डेटा होना चाहिए। मेरी फ़ाइल में, स्टोर बीबीबी के पास 8/31/2020 और 9/30/2020 के लिए कोई रिकॉर्ड नहीं है क्योंकि उन महीनों के दौरान कोई बिक्री नहीं हुई थी।
दुकान | महीना खुल गया | राज्य | Faridabad | महीने की अंतिम तिथि | बिक्री |
---|---|---|---|---|---|
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 5/31/2020 | 1000 |
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 6/30/2020 | 5000 |
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 7/30/2020 | 3000 |
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 8/31/2020 | 4000 |
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 9/30/2020 | 2000 |
बीबीबी | 6/30/2020 | सीटी | हार्टफोर्ड | 6/30/2020 | 100 |
बीबीबी | 6/30/2020 | सीटी | हार्टफोर्ड | 7/30/2020 | 200 रु |
तो इस तरह के किसी भी उदाहरण के लिए, मैं स्टोर बीबीबी के लिए 8/31 और 9/30 के लिए दो पंक्तियों को जोड़ने में सक्षम होना चाहता हूं। नई पंक्तियों को एक ही मंथली ओपनेड, स्टेट और सिटी का उपयोग सबसे हाल के महीने की समाप्ति तिथि से करना चाहिए। दोनों नई पंक्तियों के लिए बिक्री को 0 पर सेट किया जाना चाहिए। जैसा कि अभी, मैं निम्नलिखित चरण करता हूं:
- स्टोर नाम और प्रत्येक स्टोर के लिए अधिकतम माह की अंतिम तिथि के साथ डेटाफ़्रेम "मैक्सडेटाडा" बनाएं और पूरे समय श्रृंखला डेटा फ्रेम के लिए अधिकतम महीने की समाप्ति तिथि, मैं इस फ़ील्ड को "सबसे हाल की तारीख" नाम देता हूं।
दुकान | अधिकतम माह समाप्ति तिथि | सबसे हाल की तारीख |
---|---|---|
एएए | 9/30/2020 | 9/30/2020 |
बीबीबी | 7/30/2020 | 9/30/2020 |
- मुख्य समय श्रृंखला डेटाफ़्रेम से सबसे हालिया पंक्ति के साथ डेटाफ़्रेम "MostRecent" बनाएं। ऐसा करने के लिए, मैं टाइम सीरीज़ डेटाफ्रेम और मैक्सडेटाटाटा के बीच स्टोर के नाम और मैक्स मंथ एंड डेट पर एक आंतरिक जुड़ाव करता हूं।
दुकान | महीना खुल गया | राज्य | Faridabad | महीने की अंतिम तिथि | बिक्री | अधिकतम माह समाप्ति तिथि | सबसे हाल की तारीख |
---|---|---|---|---|---|---|---|
एएए | 5/31/2020 | न्यूयॉर्क | न्यूयॉर्क | 9/30/2020 | 2000 | 9/30/2020 | 9/30/2020 |
बीबीबी | 6/30/2020 | सीटी | हार्टफोर्ड | 7/30/2020 | 200 रु | 7/30/2020 | 9/30/2020 |
- स्टोर के लिए फ़िल्टर करने के लिए जहां अधिकतम महीना समाप्ति तिथि <सबसे हाल की तारीख है, जहां क्लॉज का उपयोग करके एक डेटाफ्रेम "आवश्यकताबैंक_मॉस्टरेसेंट" बनाएं। नीचे कोड देखें। तो इस उदाहरण में, NeedBackfill_MostRecent टेबल में केवल BBB स्टोर करने के लिए एक पंक्ति होगी।
RequireBackfill_Stores_MostRecent = MaxDateData.where(MaxDateData['Max Month End Date'] <MaxDateData['Most Recent Date'])
RequireBackfill_MostRecent = MostRecent.merge(RequireBackfill_Stores_MostRecent,how='inner')
- फिर मैं उन तारीखों के माध्यम से साइकिल चलाने के लिए दो नेस्टेड का उपयोग करता हूं जिन्हें मुझे भरने की आवश्यकता होती है। यह रिक्वायरमेंट को पूरा करता है।
X=[]
end = MaxDateData['Most Recent Date'][0]
for i in MonthlyData['Month End Date'].unique():
per1 = pd.date_range(start = i, end = end, freq ='M')
for val in per1:
Data=[]
Data = RequireBackfill_MostRecent[["Store"
,"Month Opened"
,"City"
,"State"
]].where(RequireBackfill_MostRecent['Max Month End date']==i).dropna()
Data["Month End Date"]= val
Data["Sales"]= 0
X.append(Data)
NewData = pd.concat(X)
- फिर मैं न्यूकाटा में अपने टाइमसेट डेटाफ़्रेम को कॉनैट का उपयोग करके जोड़ता हूं
FullData_List = [MonthlyData,NewData]
FullData=pd.concat(FullData_List)
यह पूरी प्रक्रिया काम करती है लेकिन क्या ऐसा करने के लिए अधिक कुशल तरीका है? जब मैं बड़े डेटा के साथ काम करना शुरू करता हूं तो यह महंगा हो सकता है।
जवाब
- सिर्फ
upsample
DateTime इंडेक्स का प्रयास करें । Ref: पांडा-रेज़लूशन-अपसप्ले-लास्ट-डेट-एज-ऑफ-डेटा
# group by `Store`
# with `Month End Date` column show be converted to DateTime
group.set_index(['Month End Date']).resample('M').asfreq()
- गौर करें कि:
7/30/2020
जुलाई का अंतिम दिन नहीं है।7/31/2020
है। इसलिए इस पद्धति का उपयोग करना7/30/2020
एक समस्या होगी (मंथ एंड डेट को ट्रूली डेट के रूप में परिवर्तित करें)।
ऐसा करने के लिए यहां कदम से कदम दृष्टिकोण है। यदि आपके कोई प्रश्न हैं, तो मुझे बताएं।
import pandas as pd
pd.set_option('display.max_columns', None)
c = ['Store','Month Opened','State','City','Month End Date','Sales']
d = [['AAA','5/31/2020','NY','New York','5/31/2020',1000],
['AAA','5/31/2020','NY','New York','6/30/2020',5000],
['AAA','5/31/2020','NY','New York','7/30/2020',3000],
['AAA','5/31/2020','NY','New York','8/31/2020',4000],
['AAA','5/31/2020','NY','New York','9/30/2020',2000],
['BBB','6/30/2020','CT','Hartford','6/30/2020',100],
['BBB','6/30/2020','CT','Hartford','7/30/2020',200],
['CCC','3/31/2020','NJ','Cranbury','3/31/2020',1500]]
df = pd.DataFrame(d,columns = c)
df['Month Opened'] = pd.to_datetime(df['Month Opened'])
df['Month End Date'] = pd.to_datetime(df['Month End Date'])
#select last entry for each Store
df1 = df.sort_values('Month End Date').drop_duplicates('Store', keep='last').copy()
#delete all rows that have 2020-09-30. We want only ones that are less than 2020-09-30
df1 = df1[df1['Month End Date'] != '2020-09-30']
#set target end date to 2020-09-30
df1['Target_End_Date'] = pd.to_datetime ('2020-09-30')
#calculate how many rows to repeat
df1['repeats'] = df1['Target_End_Date'].dt.to_period('M').astype(int) - df1['Month End Date'].dt.to_period('M').astype(int)
#add 1 month to month end so we can start repeating from here
df1['Month End Date'] = df1['Month End Date'] + pd.DateOffset(months =1)
#set sales value as 0 per requirement
df1['Sales'] = 0
#repeat each row by the value in column repeats
df1 = df1.loc[df1.index.repeat(df1.repeats)].reset_index(drop=True)
#reset repeats to start from 0 thru n using groupby cumcouunt
#this will be used to calculate months to increment from month end date
df1['repeats'] = df1.groupby('Store').cumcount()
#update month end date based on value in repeats
df1['Month End Date'] = df1.apply(lambda x: x['Month End Date'] + pd.DateOffset(months = x['repeats']), axis=1)
#set end date to last day of the month
df1['Month End Date'] = pd.to_datetime(df1['Month End Date']) + pd.offsets.MonthEnd(0)
#drop columns that we don't need anymore. required before we concat dfs
df1.drop(columns=['Target_End_Date','repeats'],inplace=True)
#concat df and df1 to get the final dataframe
df = pd.concat([df, df1], ignore_index=True)
#sort values by Store and Month End Date
df = df.sort_values(by=['Store','Month End Date'],ignore_index=True)
print (df)
इसका आउटपुट है:
Store Month Opened State City Month End Date Sales
0 AAA 2020-05-31 NY New York 2020-05-31 1000
1 AAA 2020-05-31 NY New York 2020-06-30 5000
2 AAA 2020-05-31 NY New York 2020-07-30 3000
3 AAA 2020-05-31 NY New York 2020-08-31 4000
4 AAA 2020-05-31 NY New York 2020-09-30 2000
5 BBB 2020-06-30 CT Hartford 2020-06-30 100
6 BBB 2020-06-30 CT Hartford 2020-07-30 200
7 BBB 2020-06-30 CT Hartford 2020-08-30 0
8 BBB 2020-06-30 CT Hartford 2020-09-30 0
9 CCC 2020-03-31 NJ Cranbury 2020-03-31 1500
10 CCC 2020-03-31 NJ Cranbury 2020-04-30 0
11 CCC 2020-03-31 NJ Cranbury 2020-05-31 0
12 CCC 2020-03-31 NJ Cranbury 2020-06-30 0
13 CCC 2020-03-31 NJ Cranbury 2020-07-31 0
14 CCC 2020-03-31 NJ Cranbury 2020-08-31 0
15 CCC 2020-03-31 NJ Cranbury 2020-09-30 0
नोट मैंने आपको अधिक भिन्नता दिखाने के लिए CCC के साथ एक और प्रविष्टि जोड़ी है।