簡體   English   中英

將DataFrame slice作為參數傳遞給函數,而無需'SettingWithCopyWarning'

[英]Passing DataFrame slice as argument to function without 'SettingWithCopyWarning'

我有一個以數據框為參數的函數,在處理此數據框時,它調用另一個函數,該函數將同一數據框的一部分作為參數傳遞給輔助函數。

所有更改均已就位,因此不會返回任何內容(由於數據框的大小)。

但是,此輔助功能引發了SettingWithCopyWarning因為它不再處理原始數據幀。

這是一個例子:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.arange(9).reshape(3,3), columns=list('abc'))
print df

def a(df):
    if df.is_copy:
        print 'a got a copy'
    df['a'] = 'a'

def b(df):
    if df.is_copy:
        print 'b got a copy'
        print df.is_copy
    df.loc[:,'b'] = 'b'

def c(df):
    a(df)
    b(df.loc[0:1,:])
    if df.is_copy:
        print 'c got a copy'
    df.loc[0:1,'c'] = 'c'

def d(df):
    new_df = df.loc[0:1].copy(deep=True)
    b(new_df)
    df.update(new_df)
    del new_df

c(df)
df

結果是:

b got a copy
<weakref at 000000000C1DE778; to 'DataFrame' at 000000000C1B9DA0>

   a  b  c
0  a  1  c
1  a  4  c
2  a  7  8

我知道一種選擇是從原始切片創建一個新的數據幀,然后將其傳遞給b ,然后傳遞給df.update(new_df)d表明它可以正常工作:

d(df)
df

產生所需的輸出:

   a  b  c
0  a  b  c
1  a  b  c
2  a  7  8

但是有沒有一種方法可以解決此問題,而無需創建新的數據SettingWithCopyWarning和提高SettingWithCopyWarning

另一個復雜之處是,有時從c中調用b可能只是簡單的b(df) ,所以切片是可選的。

謝謝。

如果要修改內容,最好只是傳遞框架和遮罩。

def b(df, row_mask):
    df.loc[row_mask,'b'] = 'foo'

雖然通常我不會修改這樣的事情,尤其是如果它的框架很大。 當您更改dtypes時,這些修改會觸發一個副本(例如,通常不應該將“ b”放入所有數字的列中,dtypes是基於列的)。

因此,更好的工作流程是:

def b(df):
    sliced = df.loc[0:1].copy()
    sliced.loc[:,'b'] = 'foo'
    return sliced

然后,您可以在結尾處簡單地包容:

result = pd.concat([b(df), df[1:]])

然后產生一個這樣的鏈,並立即連接在一起。 與就地修改相比,效率會更高(盡管如果您只修改少量值,那么我的第一種方法可能會更好地工作)。 YMMV。

暫無
暫無

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

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