返回以pandas dataframe为参数的函数输出

7 投票
2 回答
15210 浏览
提问于 2025-04-18 15:34

我有一个 pandas 数据框,长得像这样:

d = {'some_col' : ['A', 'B', 'C', 'D', 'E'],
     'alert_status' : [1, 2, 0, 0, 5]}
df = pd.DataFrame(d)

在我的工作中,有很多任务都需要用到 pandas 里的相同操作。我开始写一些标准化的函数,这些函数会接收一个数据框作为参数,然后返回一些结果。这里有一个简单的例子:

def alert_read_text(df, alert_status=None):
    if (alert_status is None):
        print 'Warning: A column name with the alerts must be specified'
    alert_read_criteria = df[alert_status] >= 1
    df[alert_status].loc[alert_read_criteria] = 1
    alert_status_dict = {0 : 'Not Read',
                         1 : 'Read'}
    df[alert_status] = df[alert_status].map(alert_status_dict)
    return df[alert_status]

我希望这个函数返回一个序列。这样的话,就可以把这个序列添加到一个已有的数据框中:

df['alert_status_text'] = alert_read_text(df, alert_status='alert_status')

但是,目前这个函数虽然能正确返回一个序列,但也会修改传入的原始列。怎么才能让传入的原始列不被修改呢?

2 个回答

0

在你的例子中,其实不需要给你的数据框(DataFrame)设置任何值。

def alert_read_text(df, alert_status):
    alert_read_criteria = df[alert_status] >= 1
    alert_status_dict = {False : 'Not Read',
                     True : 'Read'}
    return alert_read_criteria.map(alert_status_dict)

因为 alert_read_criteria 这个序列的索引和 df 是一样的,所以你之后可以这样做:df['alert_status_text'] = alert_read_text(df, alert_status='alert_status')

根据我的经验,如果你在函数中给一个作为参数传入的数据框赋值,但并不打算返回这个数据框,这通常不是个好习惯。这样做可能会隐藏函数的副作用。

6

正如你发现的,传入的数据框(dataframe)会被修改,因为参数是通过引用传递的。这在Python中是这样的,和pandas没有直接关系。

所以,如果你不想修改传入的数据框,最好先复制一份:

def alert_read_text(df, alert_status=None):
    if (alert_status is None):
        print 'Warning: A column name with the alerts must be specified'
    copy = df.copy()
    alert_read_criteria = copy[alert_status] >= 1
    copy[alert_status].loc[alert_read_criteria] = 1
    alert_status_dict = {0 : 'Not Read',
                         1 : 'Read'}
    copy[alert_status] = copy[alert_status].map(alert_status_dict)
    return copy[alert_status]

另外,你可以查看相关内容:pandas 数据框,按值复制

撰写回答