繁体   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