python - 计算重复(但唯一的记录)+ 连续记录
问题描述
我正在计算连续 + 重复日期(但唯一发票)的发票数量。我尝试将日期时间转换为字符串,然后计算序列,但它只计算每张发票的唯一日期。
# fix time format
df['Invoice Date'] = pd.to_datetime(df['Invoice Date'])
# column to find sequences
df = df.sort_values(['Vendor ID', 'Vendor Name', 'Invoice Date'])
df['continue'] = df['Invoice Date'].diff().dt.days.ne(1).cumsum()
# find time sequences
val_count = df['continue'].value_counts()
val_count = val_count[val_count.gt(1)].index.tolist()
#filter and group by Vendor
output = df[df['continue'].isin(val_count)].groupby(['Vendor ID'])['Vendor Name'].count()
电流输入:
供应商编号 | 供应商名称 | 发票日期 | 发票号码 |
---|---|---|---|
8555 | 梅西百货 | 2020 年 1 月 1 日 | 1 |
8555 | 梅西百货 | 2020 年 1 月 2 日 | 2 |
8555 | 梅西百货 | 2020 年 1 月 3 日 | 3 |
8555 | 梅西百货 | 2020 年 1 月 3 日 | 4 |
8555 | 梅西百货 | 2020 年 1 月 3 日 | 5 |
8555 | 梅西百货 | 2020 年 1 月 5 日 | 6 |
1044 | JC便士 | 2020 年 2 月 2 日 | 7 |
1044 | JC便士 | 2020 年 2 月 3 日 | 8 |
1044 | JC便士 | 2020 年 2 月 3 日 | 9 |
1044 | JC便士 | 2020 年 2 月 8 日 | 10 |
1044 | JC便士 | 2020 年 2 月 8 日 | 11 |
预期输出:
供应商编号 | 供应商名称 | 连续发票计数 |
---|---|---|
8555 | 梅西百货 | 5 |
1044 | JC便士 | 5 |
**8 月 24 日:**我正在编辑我的输入和预期输出。每个人都建议的代码是在我给出的前面的例子上工作,但不是在我的实际数据上。添加到它上面,以便它反映我遇到的问题。我已经使用了所有代码建议,但没有任何东西给 Macys 5、JC Penny 5。
- Macys 的总和为 5。发票 1-5 是连续的并且包含重复。
- JC Penny 的总和为 5。发票 7-11 包括连续 2 天,并且包含重复。
**8 月 25 日:**使用当前代码(在 @Corralien 的帮助下)和数据框添加一个新示例
d = {'Vendor ID':
{0: 8555, 1: 8555, 2: 8555, 3: 8555, 4: 8555, 5: 8555, 6: 8555,7: 8555, 8: 8555,9: 8555, 10: 8555, 11: 8555, 12: 8555, 13: 8555,
14: 1044, 15: 1044, 16: 1044, 17: 1044, 18: 1044, 19: 1044, 20: 1044, 21: 1044},
'Vendor Name':
{0: 'Macys', 1: 'Macys', 2: 'Macys', 3: 'Macys', 4: 'Macys',5: 'Macys', 6: 'Macys', 7: 'Macys', 8: 'Macys', 9: 'Macys', 10: 'Macys', 11: 'Macys', 12: 'Macys', 13: 'Macys',
14: 'JC Penny', 15: 'JC Penny', 16: 'JC Penny', 17: 'JC Penny', 18: 'JC Penny', 19: 'JC Penny', 20: 'JC Penny',21: 'JC Penny'},
'Invoice Date':
{0: '7/31/2020', 1: '7/31/2020', 2: '7/31/2020', 3: '7/31/2020', 4: '7/31/2020', 5: '2/14/2020', 6: '12/31/2019',7: '12/23/2019', 8: '7/14/2020', 9: '6/30/2020' , 10: '6/30/2020',
11: '6/30/2020', 12: '6/30/2020', 13: '6/30/2020', 14: '3/30/2020', 15: '3/20/2020', 16: '3/20/2020', 17: '3/20/2020', 18: '3/20/2020', 19: '2/27/2020', 20: '2/26/2020', 21: '2/26/2020'},
'Invoice Number':
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7}}
df = pd.DataFrame(d)
# fix time format
df['Invoice Date'] = pd.to_datetime(df['Invoice Date'])
def count_consecutive_invoice(sr):
# Find days that are less than or equal to 1 day (m1)
m1 = sr.diff().le(pd.Timedelta(days=1))
# find first days of consecutive days (which is False in m1)
m2 = (m1.eq(False) & m1.shift(-1).eq(True))
return m1.sum() + m2.sum()
output = df.groupby(['Vendor ID', 'Vendor Name'])['Invoice Date'] \
.apply(count_consecutive_invoice) \
.rename('Count of Consecutive Invoices') \
.reset_index()
电流输出:
Vendor ID Vendor Name Count of Consecutive Invoices
0 1044 JC Penny 8
1 8555 Macys 14
预期产出
Vendor ID Vendor Name Count of Consecutive Invoices
0 1044 JC Penny 7
1 8555 Macys 10
解决方案
对于每个组:
m1
: 查找天数小于或等于 1 天 (m1)m2
: 查找连续天数的第一天(在 m1 中为 False)
然后总结2个系列。
def count_consecutive_invoice(sr):
m1 = sr.sort_values().diff().le(pd.Timedelta(days=1))
m2 = (m1.eq(False) & m1.shift(-1).eq(True))
return m1.sum() + m2.sum()
# Ensure your 'Invoice Date' column is datetime64
# df['date'] = pd.to_datetime(df['date'])
>>> df.groupby(['Vendor ID', 'Vendor Name'])['Invoice Date'] \
.apply(count_consecutive_invoice) \
.rename('Count of Consecutive Invoices') \
.reset_index()
Vendor ID Vendor Name Count of Consecutive Invoices
0 1044 JC Penny 5
1 8555 Macys 5
在您的真实数据上,现在的输出是:
Vendor ID Vendor Name Count of Consecutive Invoices
0 1044 JC Penny 7
1 8555 Macys 10
推荐阅读
- java - 即使有偏差,感知器也找不到正确的线(处理)
- sql - 如何在 teradata 中实现延迟功能。
- google-cloud-platform - 在构建触发器上使用 base64 编码值时,cloudbuil.yaml 不会解组
- mysql - Kubernetes Docker/MySQL 一个服务中的多个数据库
- css - 背景颜色在带有引导 col 类的 div 内可见
- google-tag-manager - 我无法使用 Google 跟踪代码管理器,dataLayer 推送未反映分析事件面板上的任何内容
- node.js - 当我尝试创建邮件 pdf 时出现编码错误
- sql - 枢轴/取消枢轴
- arrays - VBA 中的百分位数
- sql - 从 JS ActiveX ADO 通过 MS Access 2013 中的视图查询执行 VBA 功能