簡體   English   中英

創建一個新列但創建 dataframe 的副本

[英]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 關於棄用的嘮叨。)

您的代碼存在多個問題:

  • 您正在嘗試遍歷 dataframe (但不使用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 時分配給列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設置為 0
  • 和 1 在col1值確實從前一行發生變化的行上

但在這種更簡單的情況下,您可以跳過groupby()並進行直接分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM