【问题标题】:Adding unused column combinations to DataFrame将未使用的列组合添加到 DataFrame
【发布时间】:2018-08-21 12:57:33
【问题描述】:

我有以下数据集:

print(df)

  Date      Product_Code     Quantity_ordered
01/01/18         01                 6
02/01/18         04                 3
03/01/18         01                 4
...

我想创建一个附加列“订单”,使用 Pandas,对于 每个产品day,如果订购的数量等于 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"])

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

问候

【问题讨论】:

  • 我知道我的回答迟了,但也请看看替代方案:)。

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


【解决方案1】:

您可以通过uniqueDateProduct_Code 的值使用reindex,为缺少的行创建NaNs,因此可以通过notnull 进行检查并转换为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 进行整形 - 添加NaNs,然后检查并转换为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

【讨论】:

  • 它报告:“索引包含重复条目,无法重塑”或“无法处理非唯一的多索引!” @jezrael
  • 你太棒了! @jezrael
【解决方案2】:

转换为类别并应用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2023-02-14
    • 2015-01-24
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多