Pandas:按第一次和最后一次出现填充每一行

Posted

技术标签:

【中文标题】Pandas:按第一次和最后一次出现填充每一行【英文标题】:Pandas: Fill every row by its first and last occurrence 【发布时间】:2019-12-07 18:42:42 【问题描述】:

我的数据包括发票和客户。 一位客户可以有多张发票。一张发票始终属于一位客户。发票每天更新(报告日期)。

我的目标是以天为单位计算客户的年龄(请参阅“以天为单位的年龄”列)。为了实现这一点,我采用客户报告日期的第一次出现并计算与报告日期最后一次出现的差异。

例如客户 1 出现在 08-14 到 08-15 之间。因此他/她只有 1 天大。

Report Date  Invoice No   Customer No  Amount  Age in Days
2018-08-14   A            1            50$     1
2018-08-14   B            1            100$    1
2018-08-14   C            2            75$     2

2018-08-15   A            1            20$     1
2018-08-15   B            1            45$     1
2018-08-15   C            2            70$     2

2018-08-16   C            2            40$     1
2018-08-16   D            3            100$    0
2018-08-16   E            3            60$     0

我解决了这个问题,但是效率很低,而且花费的时间太长。我的数据包含 2600 万行。下面我只计算了一位客户的年龄。

# List every customer no
customerNo = df["Customer No"].unique()
customer_age = []

# Testing for one specific customer
testCustomer = df.loc[df["Customer No"] == customerNo[0]]
testCustomer = testCustomer.sort_values(by="Report Date", ascending=True)

first_occur = testCustomer.iloc[0]['Report Date']
last_occur = testCustomer.iloc[-1]['Report Date']
age = (last_occur - first_occur).days

customer_age.extend([age] * len(testCustomer))
testCustomer.loc[:,'Customer Age']=customer_age 

有没有更好的方法来解决这个问题?

【问题讨论】:

【参考方案1】:

groupby.transformfirstlast 聚合一起使用:

grps = df.groupby('Customer No')['Report Date']    
df['Age in Days'] = (grps.transform('last') - grps.transform('first')).dt.days

[出]

  Report Date Invoice No  Customer No Amount  Age in Days
0  2018-08-14          A            1    50$            1
1  2018-08-14          B            1   100$            1
2  2018-08-14          C            2    75$            2
3  2018-08-15          A            1    20$            1
4  2018-08-15          B            1    45$            1
5  2018-08-15          C            2    70$            2
6  2018-08-16          C            2    40$            2
7  2018-08-16          D            3   100$            0
8  2018-08-16          E            3    60$            0

【讨论】:

非常感谢!这工作得很好。在 10 秒内计算了 2600 万行!! @Azrion 不错 :)【参考方案2】:

如果您需要每个客户一个值,表明其年龄,您可以使用分组依据(非常常见):

grpd = my_df.groupby('Customer No')['Report Date'].agg([min, max]).reset_index()
grpd['days_diff'] = (grpd['max'] - grpd['min']).dt.days

【讨论】:

以上是关于Pandas:按第一次和最后一次出现填充每一行的主要内容,如果未能解决你的问题,请参考以下文章

2021-09-23:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的(

对 Pandas 数据框中的每一行只运行一次函数

用 Pandas 数据框中的行填充嵌套字典

转发新行填写缺失日期的帐户

pandas如何实现缺失的行数据按上一行数据进行填充?

[Excel]空白填充上一行数据