我通过谷歌搜索找到了一些解决方案,但我始终无法正确应用这些解决方案,而且遇到了无法解决的错误,因此我不得不提出疑问。我尝试创建函数,然后将其应用到数据框,但遇到此错误,无法修复。
“'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。不可能再有其他输入,并且可能有数千行。
谢谢。
EDIT2:这是确认编辑后的答案也可以正常工作。
答案 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
的“新值”。