获取当前列最后一个非零值时另一列的值(Pandas数据帧)

时间:2018-08-16 16:29:43

标签: python pandas

我有一个与此类似的数据框,其中包含枚举日期和ID,以及在给定日期和ID下售出的商品数量:

Date  ID  num_sold
0     1   0
      2   13
1     1   6
      2   0
2     1   0
      2   0
3     1   5
      2   4

对于每个ID,我想计算上次销售发生的日期。所以我有以下数据框:

Date  ID  num_sold  last_sale
0     1   0         -1
      2   13        -1
1     1   6         -1
      2   0         0
2     1   0         1
      2   0         0
3     1   5         1
      2   4         0

我想计算列last_sale,其中1和0是给定ID时的日期值,num_sold最后为非零值。如果没有这样的最后日期(例如,数据集中的第一个月),则为-1(或者可以是nan)。

在给定的示例中,

在第1天,ID 1从未被出售过,因此我们将last_sale设置为-1。 ID 2最近一次在第0个月售出,因此我们将last_sale设置为0。

同样,在第3天,ID 1在第1个月最后一次出售,因此last_sale为1,ID 2在第0个月最后出售,因此last_sale为0。

最有效,最简洁的方法是什么?

2 个答案:

答案 0 :(得分:2)

首先,您需要为当前销售日期创建一列:

df["current_sale_date"] = 0
df.loc[df.num_sold != 0, "current_sale_date"] = df.Date

您为上次销售日期创建另一列。首先,将0替换为np.nan,以使.ffill()起作用。然后,对于每个ID,您都可以通过.fill()获得当前销售日期的值。

df.current_sale_date = df.current_sale_date.replace(0, np.nan)    
df["last_sale_date"] = df.groupby(['ID'])['current_sale_date'].ffill()

然后您将获得按ID排班的以前的销售日期

 df.last_sale_date = df.groupby(['ID'])['last_sale_date'].shift()

对于第一个日期,您设置-1

df.loc[df.Date == df.Date.idxmin(), "last_sale_date"] = -1

您将nan替换回0,因为0是一个日期

df.last_sale_date = df.last_sale_date.replace(np.nan, 0)

第一次出售ID,如果没有以前的销售日期,则设置-1

 df.loc[(df.current_sale_date == 1) & (df.last_sale_date == 0), "last_sale_date"] = -1

答案 1 :(得分:1)

首先,让我们创建您的DataFrame df1。

import pandas as pd

df1 = pd.DataFrame({'Date': ['0', '0', '1', '1', '2', '2', '3', '3'], 
                    'ID': ['1', '2', '1', '2', '1', '2', '1', '2'],
                    'num_sold': [0, 13, 6, 0, 0, 0, 5, 4]})
print(df1)

输出:

  Date ID  num_sold
0    0  1         0
1    0  2        13
2    1  1         6
3    1  2         0
4    2  1         0
5    2  2         0
6    3  1         5
7    3  2         4

现在,我们将其按ID分组,将您的逻辑应用于每个ID组,然后将这些组连接起来。

groups = []
for name, group in df1.groupby(['ID']):
    group.loc[group['num_sold'].shift(1)!=0, 'last_sale'] = group['Date'].shift(1)
    group['last_sale'] = group['last_sale'].fillna(method='ffill').fillna('-1')
    groups.append(group)

df2 = pd.concat(groups).sort_values(['Date', 'ID'])
print(df2)

您的结果:

  Date ID  num_sold last_sale
0    0  1         0        -1
1    0  2        13        -1
2    1  1         6        -1
3    1  2         0         0
4    2  1         0         1
5    2  2         0         0
6    3  1         5         1
7    3  2         4         0

祝你好运!