首页 > 解决方案 > 如何检查数据框中不同行之间的值变化并将其表示在新列中?

问题描述

每个人。

我是 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

我想检查多年来的价值变化取决于不同的产品,这是检查的逻辑:

  1. 如果一个产品的 value1 最初为 0,只需删除该行,直到 value1 变为 1。(例如 2011 年的产品 C)

  2. 如果某个产品的 value1 为 1,则将结果设置为 0。(例如 2011 年的产品 A 等)

  3. 如果某年的 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来解决这个问题,但我不知道如何获取另一个行值并比较以给出一个新值。

有人能帮我吗?

标签: pythonpandasnumpydataframe

解决方案


你的逻辑很复杂,所以我分阶段建立了它

  1. 具有第一个值和每年产品计数的临时
  2. 那么你的核心逻辑是 usingapply()和 fact have first
  3. 构建您提供的逻辑过滤条件
  4. 最后过滤到你想要的行并清理删除临时列
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

推荐阅读