[英]Pandas how to add the counters for matching rows between two dataframe columns
[英]How can I add missing rows to a pandas DataFrame depending on a date and a combination of two columns?
我有一個場景,其中我有一個包含 4 列的 dataframe:
date, product, store, sales_amt
1/1/2019, A,A,200
1/1/2019,A,B,120
1/2/2019, A,A,75
1/3/2019,A,A,69
1/3/2019,A,B,23
--
--
--
1/31/2019,A,B,49
這些日期應該跨越一整個月(例如,在本例中為 2019 年 1 月),但 dataframe 中有一些缺失的日期。
是否有人對 Python 代碼有任何提示,該代碼可以遍歷特定月份的日期並向 dataframe 添加新行,其中缺少date
、 product
/ store
組合和sales_amt
為零?
例如,2019 年 1 月 2 日 A/B 的product
/ store
組合沒有條目。
最后的目標是為每個product
/ store
組合在該月的每一天都有一個條目。
我怎樣才能做到這一點?
在set_index
之后使用resample
:
#create a dummy dataframe with data every other day
s=pd.date_range('2019-01-01', '2019-05-01', freq='2D')
df = pd.DataFrame({'Date':s, 'sales_amt':np.random.randint(100,1000,61)})
df.set_index('Date').resample('D').asfreq().fillna(0)
Output:
sales_amt
Date
2019-01-01 996.0
2019-01-02 0.0
2019-01-03 236.0
2019-01-04 0.0
2019-01-05 225.0
... ...
2019-04-27 444.0
2019-04-28 0.0
2019-04-29 756.0
2019-04-30 0.0
2019-05-01 641.0
我怎樣才能確保每個商店/產品條目都有一個日期條目?
我要使用的技巧是 pivot 需要我缺失值的列組合,然后resample
以生成缺失的日期,用 0 填充na
並最終重新整形回原始形狀和reset_index
這是一個簡短的腳本來演示這一點:
import pandas as pd
import numpy as np
products = ['tablet', 'laptop', 'phone']
stores = ['downtown', 'subburb', 'supermall']
date_range = pd.date_range('2019-01-01', '2019-03-31')
# create a sample data frame
df = pd.DataFrame({
'date': date_range,
'product': np.random.choice(products, len(date_range)),
'store': np.random.choice(stores, len(date_range)),
'sales_amt': np.random.normal(50, 10, len(date_range))
})
# remove some dates
df = df[~df.date.isin(['2019-01-10', '2019-01-11', '2019-02-07'])]
# set date as index, pivot product & store, fill na with 0
# reindex & unpivot
shape2 = df.set_index(['date', 'product', 'store']).\
unstack([1, 2]).\
resample('D').asfreq().\
fillna(0).\
stack([1, 2]).\
reset_index()
print('%d unique dates in original df' % df['date'].nunique())
print('%d rows in original df' % len(df))
print('%d unique dates after filling missing values' % shape2['date'].nunique())
print('%d rows in after filling missing values' % len(shape2))
shape2.head()
也可以通過left join
來做到這一點,首先創建所有所需組合的 dataframe,然后將源數據框left joined
。 這種方法需要稍長的時間來表達,但對於來自 SQL 思維模式的人來說會更直觀。
cross_product = pd.MultiIndex.from_product([
pd.date_range(df.date.min(), df.date.max()),
df['product'].unique(),
df.store.unique()]
).to_frame().\
reset_index(drop=True).\
rename({0:'date', 1:'product', 2:'store'}, axis=1)
final_df = cross_product.merge(df,
left_on=['date', 'product', 'store'],
right_on=['date', 'product', 'store'],
how='left').fillna(0)
我相信這可以通過創建整個月的日期索引(在您的情況下是第一個日期和最后一個日期之間的所有日期)然后將其合並到原始 dataframe 上來完成。
因此,如果“df”是包含日期、產品、商店和 sales_amt 的原始 dataframe,那么添加以下代碼應該會有所幫助。
all_dates = pd.DataFrame(pd.date_range(df['date'].min(), df['date'].max()))
all_dates.rename(columns = {0: 'date'}, inplace = True)
df = all_dates.merge(df, on = 'date', how = 'left')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.