python - 如何检查数据框中不同行之间的值变化并将其表示在新列中?
问题描述
每个人。
我是 python 和 pandas 的新手,我遇到了一个问题,我需要检查某个列的值是否随时间变化(不同的行)。我完全不知道如何解决这个问题。
我创建了一个简单的示例来清楚地说明它:
df = pd.DataFrame({"Year":[2011,2012,2013,2014,2011,2014,2014,2014,2011,2012,2012,2015],"Product":['A','A','A','A','B','B','B','B','C','C','C','C'],"Value1":[1,1,1,0,1,1,0,1,0,1,1,1]},index=['A','A','A','A','B','B','B','B','C','C','C','C'])
df
Year Product Value1
A 2011 A 1
A 2012 A 1
A 2013 A 1
A 2014 A 0
B 2011 B 1
B 2014 B 1
B 2014 B 0
B 2014 B 1
C 2011 C 0
C 2012 C 1
C 2012 C 1
C 2015 C 1
我想检查多年来的价值变化取决于不同的产品,这是检查的逻辑:
如果一个产品的 value1 最初为 0,只需删除该行,直到 value1 变为 1。(例如 2011 年的产品 C)
如果某个产品的 value1 为 1,则将结果设置为 0。(例如 2011 年的产品 A 等)
如果某年的 value1 从 1 变为 0,则将结果设置为 1,并删除该产品在同一年内的其他行(例如 2014 年的产品 B)
所以最终的结果应该是这样的:
df2 = pd.DataFrame({"Year":[2011,2012,2013,2014,2011,2014,2012,2012,2015],"Product":['A','A','A','A','B','B','C','C','C'],"Value1":[1,1,1,0,1,0,1,1,1],'result':[0,0,0,1,0,1,0,0,0]},index=['A','A','A','A','B','B','C','C','C'])
df2
Year Product Value1 result
A 2011 A 1 0
A 2012 A 1 0
A 2013 A 1 0
A 2014 A 0 1
B 2011 B 1 0
B 2014 B 0 1
C 2012 C 1 0
C 2012 C 1 0
C 2015 C 1 0
我试图用它pd.apply
来解决这个问题,但我不知道如何获取另一个行值并比较以给出一个新值。
有人能帮我吗?
解决方案
你的逻辑很复杂,所以我分阶段建立了它
- 具有第一个值和每年产品计数的临时列
- 那么你的核心逻辑是 using
apply()
和 fact have first - 构建您提供的逻辑过滤条件
- 最后过滤到你想要的行并清理删除临时列
df = pd.DataFrame({"Year":[2011,2012,2013,2014,2011,2014,2014,2014,2011,2012,2012,2015],"Product":['A','A','A','A','B','B','B','B','C','C','C','C'],"Value1":[1,1,1,0,1,1,0,1,0,1,1,1]},index=['A','A','A','A','B','B','B','B','C','C','C','C'])
df = df.assign(
# need first value for logic
first=df.groupby("Product")["Value1"].transform("first"),
# need count for delete rows logic
count=df.groupby(["Product","Year"])["Value1"].transform("count"),
# core logic ...
result=lambda dfa: dfa.apply(lambda r: 0 if ((r["first"]==0) or (r["first"]==r["Value1"])) else 1, axis=1),
# delete / drop rows logic
delete=lambda dfa: dfa.apply(lambda r: r["count"]>1 and r["result"]!=r["first"], axis=1)
).drop(["first","count"], axis=1) # drop temp columns used in logic
# filter and drop column used for filter
df = df[~df["delete"]].drop(["delete"], axis=1)
print(df.to_string())
输出
Year Product Value1 result
A 2011 A 1 0
A 2012 A 1 0
A 2013 A 1 0
A 2014 A 0 1
B 2011 B 1 0
B 2014 B 0 1
C 2011 C 0 0
C 2012 C 1 0
C 2012 C 1 0
C 2015 C 1 0
推荐阅读
- acumatica - 如何在选择器中获取 DAC 字段显示名称当我们在 Acumatica 中显示连接 2 个表的数据字段时?
- java - 我试图实现碰撞,我的游戏现在拒绝加载
- npm - 天蓝色 devops npm 任务
- javascript - 函数不能用“new Map()”迭代
- c# - 如何使用另一个脚本中的变量
- c# - 如何修复此错误:“预期标识符”
- python - 获得 Deeplab 对小/欠平衡类的更严格的分割结果
- mysql - UnhandledPromiseRejectionWarning:错误:未找到 Category#products 的实体元数据
- memory-management - 运行时错误:CUDA 内存不足。试图分配...但内存是空的
- java - 需要将 Arraylist 从 java 程序传递给 R 脚本作为参数