我想检查上面一行的值,并看到它与当前行相同。我找到了一个很好的答案here:df['match'] = df.col1.eq(df.col1.shift())
就是您正在比较的col1
。
但是,当我尝试时,收到了SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
警告。我的col1
是一个字符串。我知道您可以禁止显示警告,但是如何检查上面的同一行并确保不创建数据框的副本?即使发出警告,我也确实获得了期望的输出,但是很好奇是否存在更好的方法。
import pandas as pd
data = {'col1':['a','a','a','b','b','c','c','c','d','d'],
'week':[1,1,1,1,1,2,2,2,2,2]}
df = pd.DataFrame(data, columns=['col1','week'])
df['check_condition'] = 1
while sum(df.check_condition) != 0:
for week in df.week:
wk = df.loc[df.week == week]
wk['match'] = wk.col1.eq(wk.col1.shift()) # <-- where the warning occurs
# fix the repetitive value...which I have not done yet
# for now just exit out of the while loop
df.loc[df.week == week,'check_condition'] = 0
您不能忽略熊猫SettingWithCopyWarning
!100%告诉您代码根本无法按预期运行。停止,调查并修复它。 (这不是您可以过滤掉的不可忽略的事情,就像FutureWarning关于弃用的na。)
在您的情况下,它是在wk
上触发的,这是来自数据帧df
的切片,而不是实际数据帧。它告诉您A value is trying to be set on a copy of a slice from a DataFrame.
因此,为了解决这个问题,让我们退后一步,弄清楚您的代码正在尝试重写什么。
您正在尝试遍历一个数据帧,对其进行切片(在子数据帧wk
中,是副本),然后分配给不存在的新列wk['match']
。这很糟糕,您不应该这样做。稍后,您还尝试在df上进行迭代时分配给列df['check_condition']
,这也很糟糕。
解决方案:
df['check_condition'] = df['col1'].eq(df['col1'].shift()).astype(int)
df
col1 week check_condition
0 a 1 0
1 a 1 1
2 a 1 1
3 b 1 0
4 b 1 1
5 c 2 0
6 c 2 1
7 c 2 1
8 d 2 0
9 d 2 1
通常,对于要遍历数据帧组的更复杂的代码,应使用split-apply-combine代替。
wk.col1.eq(wk.col1.shift())
分组,即col1
值与前一行没有变化的行check_condition
设置为0col1
值确实与前一行发生变化的行上的1但是实际上,在这种情况下,您可以跳过groupby()
并直接分配。