एक समय सीमा डेटाफ़्रेम के लिए पंक्तियों को कैसे जोड़ा जाए?

Dec 31 2020

मैं एक प्रोग्राम लिख रहा हूं जो एक टाइमस्टाइल एक्सेल फाइल में डेटाफ्रेम में लोड होगा, फिर मैं कुछ बुनियादी गणनाओं का उपयोग करके कई नए कॉलम बनाता हूं। मेरा कार्यक्रम कभी-कभी एक्सेल फाइलों में पढ़ा जा रहा है जो कुछ रिकॉर्ड के लिए महीनों से गायब हैं। इसलिए नीचे दिए गए उदाहरण में मेरे पास दो अलग-अलग स्टोर के लिए मासिक बिक्री डेटा है। स्टोर अलग-अलग महीनों के दौरान खुलते हैं, इसलिए उनकी पहली महीने की समाप्ति तिथि अलग-अलग होगी। लेकिन दोनों में 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 पर सेट किया जाना चाहिए। जैसा कि अभी, मैं निम्नलिखित चरण करता हूं:

  1. स्टोर नाम और प्रत्येक स्टोर के लिए अधिकतम माह की अंतिम तिथि के साथ डेटाफ़्रेम "मैक्सडेटाडा" बनाएं और पूरे समय श्रृंखला डेटा फ्रेम के लिए अधिकतम महीने की समाप्ति तिथि, मैं इस फ़ील्ड को "सबसे हाल की तारीख" नाम देता हूं।
दुकान अधिकतम माह समाप्ति तिथि सबसे हाल की तारीख
एएए 9/30/2020 9/30/2020
बीबीबी 7/30/2020 9/30/2020
  1. मुख्य समय श्रृंखला डेटाफ़्रेम से सबसे हालिया पंक्ति के साथ डेटाफ़्रेम "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
  1. स्टोर के लिए फ़िल्टर करने के लिए जहां अधिकतम महीना समाप्ति तिथि <सबसे हाल की तारीख है, जहां क्लॉज का उपयोग करके एक डेटाफ्रेम "आवश्यकताबैंक_मॉस्टरेसेंट" बनाएं। नीचे कोड देखें। तो इस उदाहरण में, 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')
  1. फिर मैं उन तारीखों के माध्यम से साइकिल चलाने के लिए दो नेस्टेड का उपयोग करता हूं जिन्हें मुझे भरने की आवश्यकता होती है। यह रिक्वायरमेंट को पूरा करता है।
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) 
  1. फिर मैं न्यूकाटा में अपने टाइमसेट डेटाफ़्रेम को कॉनैट का उपयोग करके जोड़ता हूं
FullData_List = [MonthlyData,NewData]
FullData=pd.concat(FullData_List)

यह पूरी प्रक्रिया काम करती है लेकिन क्या ऐसा करने के लिए अधिक कुशल तरीका है? जब मैं बड़े डेटा के साथ काम करना शुरू करता हूं तो यह महंगा हो सकता है।

जवाब

Ferris Dec 31 2020 at 14:08
  1. सिर्फ upsampleDateTime इंडेक्स का प्रयास करें । Ref: पांडा-रेज़लूशन-अपसप्ले-लास्ट-डेट-एज-ऑफ-डेटा
# group by `Store`
# with `Month End Date` column show be converted to DateTime

group.set_index(['Month End Date']).resample('M').asfreq()
  1. गौर करें कि: 7/30/2020जुलाई का अंतिम दिन नहीं है। 7/31/2020है। इसलिए इस पद्धति का उपयोग करना 7/30/2020एक समस्या होगी (मंथ एंड डेट को ट्रूली डेट के रूप में परिवर्तित करें)।
JoeFerndz Dec 31 2020 at 16:14

ऐसा करने के लिए यहां कदम से कदम दृष्टिकोण है। यदि आपके कोई प्रश्न हैं, तो मुझे बताएं।

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 के साथ एक और प्रविष्टि जोड़ी है।