我有一个数据集,其中包含给定公司在给定月份的销售额和利润。在某些月份,公司将不开展任何业务,因此该月份的数据中会丢失该数据。我想为这些缺失的月份创建行,并用 0 填充金额/利润变量。
重现数据的代码:
import pandas as pd
import numpy as np
import itertools
from datetime import datetime
np.random.seed(2021)
company_list = ['Company_A', 'Company_B', 'Company_C']
datelist = pd.date_range(start="2020-01-01", end='2020-08-01', freq='MS').to_list()
df = pd.DataFrame(list(itertools.product(company_list, datelist)))
df.columns = ['Company', 'Date']
df['Amount'] = np.random.choice(range(0,10000), df.shape[0])
df['Profit'] = np.random.choice(range(0,10000), df.shape[0])
df['Date'] = df['Date'] + pd.tseries.offsets.MonthEnd(1)
df = df.drop([0,1,5,10,11,15,16,17,22,23]).reset_index(drop=True) #Dropping some rows just to illustrate what my data looks like
df
我已经使用我在此 post 中找到的帮助弄清楚了如何执行此操作,但是它使用“日期”列中所有日期的最小/最大范围。因为对我公司的观察开始和结束的时间不同,这增加了我第一次观察它们之前和它们从数据中消失之后的日期,这不是我想要的。
df.set_index(
['Date', 'Company']
).unstack(
fill_value = 0
).asfreq(
'M'
).stack().sort_index(level=1).reset_index()
我想要的是只添加由特定组的最小/最大日期导致的缺失日期,即只添加介于两者之间的日期,而不是末尾的日期。
数据的外观:
答案 0 :(得分:0)
这样做就行了:
df.drop_duplicates(
['Date', 'Company'], 'last'
).groupby('Company').apply(
lambda x: x.set_index('Date').asfreq('M', fill_value = 0)
).drop('Company', axis = 1).reset_index()