熊猫从上一行减去另一列中的值

时间:2018-09-05 17:04:30

标签: python pandas

我是Python的初学者,现在有一个按标识符,id_number和contract_year_month排序的数据框(名为df),到目前为止,顺序是这样的:

**identifier id_number contract_year_month collection_year_month**
   K001        1         2018-01-03           2018-01-09
   K001        1         2018-01-08           2018-01-10
   K001        2         2018-01-01           2018-01-05
   K001        2         2018-01-15           2018-01-18
   K002        4         2018-01-04           2018-01-07
   K002        4         2018-01-09           2018-01-15

,并想添加一个名为“ date_difference”的列,该列由基于标识符和id_number的contract_year_month减去上一行的collection_year_month(例如2018-01-08减去2018-01-09)组成, 这样df将会是:

**identifier id_number contract_year_month collection_year_month date_difference**
   K001        1         2018-01-03           2018-01-09            
   K001        1         2018-01-08           2018-01-10           -1
   K001        2         2018-01-01           2018-01-05
   K001        2         2018-01-15           2018-01-18           10
   K002        4         2018-01-04           2018-01-07
   K002        4         2018-01-09           2018-01-15            2

我已经将contract_year_month和collection_year_month列的类型转换为datetime,并尝试使用简单的shift函数或iloc进行工作,但都不起作用。

df["date_difference"] = df.groupby(["identifier", "id_number"])["contract_year_month"]

有什么方法可以使用groupby来获取另一列中当前行值和上一行值之间的差,该值由两个标识符分隔吗? (我已经搜索了一个小时,但找不到任何提示...)如果您能给我一些建议,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

这是一种实现此目的的方法。

首先创建一个布尔掩码,然后使用numpy.whereSeries.shift创建date_difference列:

mask = df.duplicated(['identifier', 'id_number'])

df['date_difference'] = (np.where(mask, (df['contract_year_month'] - 
                                         df['collection_year_month'].shift(1)).dt.days, np.nan))

[输出]

    identifier  id_number   contract_year_month collection_year_month   date_difference
0   K001    1   2018-01-03  2018-01-09  NaN
1   K001    1   2018-01-08  2018-01-10  -1.0
2   K001    2   2018-01-01  2018-01-05  NaN
3   K001    2   2018-01-15  2018-01-18  10.0
4   K002    4   2018-01-04  2018-01-07  NaN
5   K002    4   2018-01-09  2018-01-15  2.0

答案 1 :(得分:1)

这是使用您的grouby()已更新,基于@piRSquared的反馈)的一种方法:

In []:
(df['collection_year_month']
 .groupby([df['identifier'], df['id_number']])
 .shift() - df['contract_year_month']).dt.days

Out[]:
0     NaN
1    -1.0
2     NaN
3    10.0
4     NaN
5     2.0
dtype: float64

您可以将其分配给df['date_difference']