我想检查上面一行的值,看它是否与当前行相同。我找到了一个很好的答案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
答案 0 :(得分:1)
您不能忽略大熊猫SettingWithCopyWarning
!
100%告诉您代码根本无法按预期运行。停止,调查并修复它。 (这不是您可以过滤掉的不可忽略的东西,就像熊猫关于折旧问题的FutureWarning一样。)
您的代码有多个问题:
groupby()
),对其进行切片(在子数据帧wk
中,它是切片的副本)... < / li>
wk['match']
。这很糟糕,您不应该这样做。 (您可以初始化df['match'] = np.nan
,但是尝试在wk
中分配给副本仍然是错误的)... SettingWithCopyWarning
时,会触发wk['match']
。它告诉您wk
是数据帧df
的切片的副本,而不是df
本身。因此,就像它告诉您的那样:A value is trying to be set on a copy of a slice from a DataFrame.
只会在每次wk
被循环覆盖时才丢弃该分配,因此即使您可以强制它在wk
上工作,也是错误的。这就是SettingWithCopyWarning
是代码气味的原因,因此您不应该首先复制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
通常,对于要根据某些分组条件遍历每组数据框的更复杂的代码,请改用groupby()
and split-apply-combine。
wk.col1.eq(wk.col1.shift())
分组,即col1
值与前一行不变的行check_condition
设置为0 col1
值与前一行确实发生变化的行上为1 但是在这种简单的情况下,您可以跳过groupby()
并直接进行分配。