我有以下数据集:
print(df)
Date Product_Code Quantity_ordered
01/01/18 01 6
02/01/18 04 3
03/01/18 01 4
...
我想创建一个额外的列"订单",使用Pandas,对于每个产品和天,如果有,则等于1是订购数量,否则为0;例如:
print(final_df)
Date Product_Code Order
01/01/18 01 1
01/01/18 04 0
02/01/18 04 1
02/01/18 01 0
03/01/18 01 1
03/01/18 04 0
...
我试过了:
a = pd.date_range(min(df["Date"]), max(df["Date"]))
final_df = pd.merge(df, a, on = ["Date", "Product_Code"])
但是它报告了一个错误,说它无法处理日期时间;此外,我不认为这是最有效的方式,我不知道如何创建最终的二进制变量。
此致
答案 0 :(得分:0)
您可以使用Date
Product_Code
和NaN
的值reindex
,为缺失的行创建notnull
,因此可以{{1}进行检查并转换为0,1
:
mux = pd.MultiIndex.from_product([df['Date'].unique(), df['Product_Code'].unique()],
names=('Date','Product_Code'))
df1 = (df.set_index(['Date','Product_Code'])['Quantity_ordered']
.reindex(mux)
.notnull()
.astype(int)
.reset_index()
.rename(columns={'Quantity_ordered':'Order'}))
替代解决方案是使用unstack
进行重塑 - 添加NaN
,然后检查并转换为0,1
,最后转换回使用stack
:
df1 = (df.set_index(['Date','Product_Code'])['Quantity_ordered']
.unstack()
.notnull()
.astype(int)
.stack()
.reset_index(name='Order')
)
print (df1)
Date Product_Code Order
0 01/01/18 01 1
1 01/01/18 04 0
2 02/01/18 01 0
3 02/01/18 04 1
4 03/01/18 01 1
5 03/01/18 04 0
使用重复项的解决方案:
print (df)
Date Product_Code Quantity_ordered
0 01/01/18 01 6
1 01/01/18 01 7
2 02/01/18 04 3
3 03/01/18 01 4
from itertools import product
df1 = pd.DataFrame(list(product(df['Date'].unique(), df['Product_Code'].unique())),
columns=('Date','Product_Code'))
print (df1)
Date Product_Code
0 01/01/18 01
1 01/01/18 04
2 02/01/18 01
3 02/01/18 04
4 03/01/18 01
5 03/01/18 04
df2 = pd.merge(df, df1, how='right').sort_values(['Date','Product_Code'])
df2 = (df2.rename(columns={'Quantity_ordered':'Order'})
.assign(Order=lambda x:x['Order'].notnull().astype(int)))
print (df2)
Date Product_Code Order
0 01/01/18 01 1
1 01/01/18 01 1
4 01/01/18 04 0
5 02/01/18 01 0
2 02/01/18 04 1
3 03/01/18 01 1
6 03/01/18 04 0
答案 1 :(得分:0)
转换为类别并应用groupby.sum
。这将检索您所需类别的笛卡尔积,这是您正在寻找的。 p>
import pandas as pd
df = pd.DataFrame({'Date': ['01/01/18', '02/01/18', '03/01/18'],
'Product_Code': ['01', '04', '01'],
'Quantity_ordered': [6, 3, 4]})
# Convert to categories
df['Date'] = df['Date'].astype('category')
df['Product_Code'] = df['Product_Code'].astype('category')
# Groupby categories to retrieve cartesian product
df = df.groupby(['Date', 'Product_Code'], as_index=False)['Quantity_ordered'].sum()
# Define Order column
df['Quantity_ordered'] = df['Quantity_ordered'].notnull().astype(int)
<强>结果强>
Date Product_Code Quantity_ordered
0 01/01/18 01 1
1 01/01/18 04 0
2 02/01/18 01 0
3 02/01/18 04 1
4 03/01/18 01 1
5 03/01/18 04 0