[英]Creating a new column but creates copy of dataframe
我想檢查上面行的值,看看它與當前行相同。 我在這里找到了一個很好的答案: 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
是一個字符串。 我知道您可以禁止顯示警告,但我將如何檢查上面的同一行並確保我沒有創建 dataframe 的副本? 即使有警告,我確實得到了我想要的 output,但很好奇是否存在更好的方法。
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
您不能忽略 pandas SettingWithCopyWarning
,它 100% 告訴您您的代碼無法按預期工作。 如果有的話,停止。 調查並修復它,(這不是您可以過濾掉的可忽略的事情。就像 pandas FutureWarning 關於棄用的嘮叨。)
您的代碼存在多個問題:
groupby()
),對其切片(在子數據幀wk
中,是的切片的副本)...wk['match']
。 這很糟糕,你不應該這樣做。 (您可以初始化df['match'] = np.nan
,但嘗試分配給wk
中的副本仍然是錯誤的)...wk['match']
時,會觸發SettingWithCopyWarning
。 它告訴您wk
是來自 dataframe 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
更一般地說,對於更復雜的代碼,您希望根據某些分組標准迭代每組 dataframe,您可以使用groupby()
和split-apply-combine代替。
wk.col1.eq(wk.col1.shift())
分組,即col1
值與前一行沒有變化的行check_condition
設置為 0col1
值確實從前一行發生變化的行上但在這種更簡單的情況下,您可以跳過groupby()
並進行直接分配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.