将未使用的列组合添加到DataFrame

时间:2018-03-13 10:06:01

标签: python python-3.x pandas dataframe subset

我有以下数据集:

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"])

但是它报告了一个错误,说它无法处理日期时间;此外,我不认为这是最有效的方式,我不知道如何创建最终的二进制变量。

此致

2 个答案:

答案 0 :(得分:0)

您可以使用Date Product_CodeNaN的值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。这将检索您所需类别的笛卡尔积,这是您正在寻找的。

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