python - 如何检查前几个月列表中是否存在标识符
问题描述
我试图确定一个标识符是否在给定月份首先出现(即它是标识符列表中的“新”)。下面是第一次尝试,但它a3
在 2020 年 2 月 28 日将标识符标记为旧,尽管它在 2020 年 1 月 31 日不在列表中。
请注意,这是一个简化的示例:实际上,我将有更多的按列分组,而不仅仅是日期,并且我需要检查标识符是否是由日期、行业、年龄组合创建的“单元格”的新标识符等。可能有很多。
import pandas as pd, numpy as np
data = """
date identifier value
31-Dec-2019 a1 10
31-Dec-2019 a2 20
31-Dec-2019 a3 30
31-Jan-2020 a1 40
31-Jan-2020 a2 50
31-Jan-2020 a4 60
31-Jan-2020 a5 60
28-Feb-2020 a1 70
28-Feb-2020 a4 80
28-Feb-2020 a3 90
"""
res=[]
for row in [el.split() for el in data.splitlines()][1:]:
rrow=[]
for col in row:
try:
if float(col):
col = np.float32(col)
except:
pass
rrow.append(col)
res.append(rrow)
df = pd.DataFrame(data=res[1:], columns=res[0])
df.date = pd.to_datetime(df.date)
df = df.set_index(["date", "identifier"]).sort_index()
df["valprev"] = df.groupby(level="identifier")["value"].shift(1)
df["isnew"] = df.valprev.isnull(
解决方案
使用pd.to_datetime
将date
列转换为熊猫datetime
系列:
df['date'] = pd.to_datetime(df['date'])
然后使用:
s1 = df.groupby('date')['identifier'].value_counts()
s2 = s1.unstack().diff().replace({0: False, np.nan: True}).stack()
df['isnew'] = df.set_index(['date', 'identifier']).index.map(s2)
细节:
使用DataFrame.groupby
on和date
聚合列:identifier
Groupby.value_counts
# print(s1):
date identifier
2019-12-31 a1 1
a2 1
a3 1
2020-01-31 a1 1
a2 1
a4 1
a5 1
2020-02-28 a1 1
a3 1
a4 1
Name: identifier, dtype: int64
Series.unstack
在序列s1
上使用reshape
它,然后用于DataFrame.diff
计算标识符计数之间的连续差异,这一步将有助于识别repeated
标识符的出现previous month
,接下来使用DataFrame.stack
它再次将其转换为MultiLevel
名为的索引序列s2
。
# s1.unstack().diff()
identifier a1 a2 a3 a4 a5
date
2019-12-31 NaN NaN NaN NaN NaN
2020-01-31 0.0 0.0 NaN NaN NaN
2020-02-28 0.0 NaN NaN 0.0 NaN
# print(s2) # this series will be use to map in next step
date identifier
2019-12-31 a1 True
a2 True
a3 True
a4 True
a5 True
2020-01-31 a1 False
a2 False
a3 True
a4 True
a5 True
2020-02-28 a1 False
a2 True
a3 True
a4 False
a5 True
dtype: bool
用于set_index
将数据帧的索引设置df
为date
和identifier
并用于Series.map
从 的值映射此索引s2
,将此映射的值分配给新列isnew
:
# print(df)
date identifier value isnew
0 2019-12-31 a1 10 True
1 2019-12-31 a2 20 True
2 2019-12-31 a3 30 True
3 2020-01-31 a1 40 False
4 2020-01-31 a2 50 False
5 2020-01-31 a4 60 True
6 2020-01-31 a5 60 True
7 2020-02-28 a1 70 False
8 2020-02-28 a4 80 False
9 2020-02-28 a3 90 True
推荐阅读
- c# - 如何使用 C# 在旧版边缘浏览器的新窗口中启动 url
- python - 消除表达式的所有前导零
- spring-boot - 在 EC2 实例上运行时,Spring Boot 将文件上传到 S3 太慢
- apache-kafka - 在 Ubuntu 18.04 EC2 上安装 Thingsboard 时出错“[main] ERROR otserver.queue.kafka.TbKafkaAdmin - 无法获取所有主题。”
- c# - 列表视图上的选项卡焦点正在跳过标题
- c# - 使用 id 类的自动映射器表达式映射到字符串会导致 EFCore 中的翻译错误
- jenkins - Jenkins 中的电子邮件扩展插件无法解析 Outlook 电子邮件的全局变量和 groovy 模板
- typescript - 类型'typeof TouchableNativeFeedback'.ts(2339)上不存在属性'Ripple'
- r - 如何通过在 R 中生成新列来拆分这些数据
- git - 重新设置从主分支分支出来的分支的分支时要采取的步骤