熊猫:比较连续的行

时间:2019-03-19 21:17:37

标签: python pandas

我通过谷歌搜索找到了一些解决方案,但我始终无法正确应用这些解决方案,而且遇到了无法解决的错误,因此我不得不提出疑问。我尝试创建函数,然后将其应用到数据框,但遇到此错误,无法修复。

  

“'numpy.int64'对象没有属性'shift'”

所以,我有第一个数据帧

    A   B
1   0   0
2   1   0
3   0   0
4   0   0
5   0   1
6   0   0

结果应如下所示:

    A   B
1   0   0
2   1   0
3   1   0
4   1   0
5   1   1
6   0   0

因此,当A列中出现1时,它应该在A列中再次出现,直到B列中出现1。不可能再有其他输入,并且可能有数千行。

谢谢。

编辑:Samplesizedata

EDIT2:这是确认编辑后的答案也可以正常工作。

1 个答案:

答案 0 :(得分:1)

尝试以下代码:

df.A = (df.A.cumsum() != df.B.shift().cumsum()\
    .fillna(0, downcast='infer')).astype(int)

说明:

  • df.A.cumsum()产生一个递增的数字序列 在1列中的每个A上。
  • df.B.shift().cumsum()为列B产生相似的序列, 但向下移动了1位,并且NaN排在第一位。
  • fillna(0, downcast='infer')NaN替换初始的0 并将整个序列的类型改回int
  • (... != ...)计算一个布尔向量-几乎是您想要的。
  • astype(int)转换上面的 boolean 向量 到 int 向量
  • 将整个结果替换为A列。

编辑

在您发表评论并获得了更长的原始数据后,我决定解决 问题完全是另一种方式。

从定义函数开始,将其应用于每一行:

def xx(row):
    global nextRes
    currRes = nextRes   # Set current result from the saved value
    if row.B == 1:
        nextRes = 0                 # Off next
    else:           # B == 0
        if row.A == 0:
            pass                    # No change
        else:       # A == 1
            currRes = nextRes = 1   # On now
    return currRes

此函数使用全局变量nextRes-应该是什么 下一个行的结果。

B == 1(无论A的值如何)表示“关闭”,但开始 在下一个行中

否则(B == 0)我们有2种可能性:

  • A == 0-不变,
  • A == 1-“立即打开” 立即

然后,要执行任务,请初始化“ next”值并应用 以上功能用于每一行:

nextRes = 0
df.A = df.apply(xx, axis=1)

(可选)要轻松比较源数据和结果,请运行:

df['new_A'] = df.apply(xx, axis=1)

这样,您将同时拥有两者源数据和A的“新值”。