使用用户定义函数时如何让两个函数返回?

Posted

技术标签:

【中文标题】使用用户定义函数时如何让两个函数返回?【英文标题】:How do you get two functions to return when using a user-defined function? 【发布时间】:2018-07-06 14:41:20 【问题描述】:

我刚刚开始使用用户定义的函数,所以这可能不是一个很复杂的问题,请见谅。

我有几个数据框,它们都有一个名为“interval_time”的列(例如),我想将此列重命名为“时间戳”,然后将此重命名的列放入索引中。

我知道我可以用这个手动完成;

df = df.rename(index=str, columns='interval_time': 'Timestamp')
df = df.set_index('Timestamp')

但现在我想定义一个名为 rename 的函数来为我做这件事。我已经看到这是可行的;

def rename_col(data, col_in='tempus_interval_time', col_out='Timestamp'):
    return data.rename(index=str, columns=col_in: col_out, inplace=True)

但是当我尝试添加第二个函数时,它似乎没有做任何事情,但是如果我将第二部分定义为它自己的函数并运行它,它似乎确实可以工作。

我正在尝试这个

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
    return data.rename(index=str, columns=col_in: col_out, inplace=True)
    return data.set_index('Timestamp', inplace=True)

我使用的数据框具有以下形式;

df_scada
              interval_time                 A         ...             X                 Y 
0       2010-11-01 00:00:00                0.0        ...                396.36710         381.68860
1       2010-11-01 00:05:00                0.0        ...                392.97974         381.40634
2       2010-11-01 00:10:00                0.0        ...                390.15695         379.99493
3       2010-11-01 00:15:00                0.0        ...                389.02786         379.14810

【问题讨论】:

您是否尝试过将它们链接在一起? return df.rename(...).set_index(...) 当一个 return 语句在 python 中被求值时,它退出函数调用。任何进一步的返回语句都将被忽略。一次返回多个对象的常用方法是返回包含对象的元组。但是,正如 Martijn 的回答所指出的那样,如果您正在修改对象,则不必返回任何内容。 【参考方案1】:

您无需返回任何内容,因为您的操作已就地完成。您可以在函数中进行就地更改:

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
    data.rename(index=str, columns=col_in: col_out, inplace=True)
    data.set_index('Timestamp', inplace=True)

以及对您传递给函数的数据框的任何其他引用都会看到所做的更改:

>>> import pandas as pd
>>> df = pd.DataFrame('interval_time': pd.to_datetime(['2010-11-01 00:00:00', '2010-11-01 00:05:00', '2010-11-01 00:10:00', '2010-11-01 00:15:00']),
...     'A': [0.0] * 4, index=range(4))
>>> df
     A       interval_time
0  0.0 2010-11-01 00:00:00
1  0.0 2010-11-01 00:05:00
2  0.0 2010-11-01 00:10:00
3  0.0 2010-11-01 00:15:00
>>> def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
...     data.rename(index=str, columns=col_in: col_out, inplace=True)
...     data.set_index('Timestamp', inplace=True)
...
>>> rename_n_index(df, 'interval_time')
>>> df
                       A
Timestamp
2010-11-01 00:00:00  0.0
2010-11-01 00:05:00  0.0
2010-11-01 00:10:00  0.0
2010-11-01 00:15:00  0.0

在上面的示例中,df 对数据框的引用显示了函数所做的更改。

如果您删除 inplace=True 参数,方法调用将返回一个新的数据框对象。您可以将中间结果存储为局部变量,然后将第二种方法应用于该局部变量中引用的数据框:

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
    renamed = data.rename(index=str, columns=col_in: col_out)
    return renamed.set_index('Timestamp')

或者您可以将方法调用直接链接到返回的对象:

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
    return data.rename(index=str, columns=col_in: col_out)\
               .set_index('Timestamp'))

因为renamed 已经是一个新的数据框,您可以将set_index() 调用就地应用于该对象,然后也只返回renamed

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
    renamed = data.rename(index=str, columns=col_in: col_out)
    renamed.set_index('Timestamp', inplace=True)
    return renamed

无论哪种方式,这都会返回一个 new 数据框对象,而原始数据框保持不变:

>>> def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):
...     renamed = data.rename(index=str, columns=col_in: col_out)
...     return renamed.set_index('Timestamp')
...
>>> df = pd.DataFrame('interval_time': pd.to_datetime(['2010-11-01 00:00:00', '2010-11-01 00:05:00', '2010-11-01 00:10:00', '2010-11-01 00:15:00']),
...     'A': [0.0] * 4, index=range(4))
>>> rename_n_index(df, 'interval_time')
                       A
Timestamp
2010-11-01 00:00:00  0.0
2010-11-01 00:05:00  0.0
2010-11-01 00:10:00  0.0
2010-11-01 00:15:00  0.0
>>> df
     A       interval_time
0  0.0 2010-11-01 00:00:00
1  0.0 2010-11-01 00:05:00
2  0.0 2010-11-01 00:10:00
3  0.0 2010-11-01 00:15:00

【讨论】:

方法链接是第四种可能性,即renamed = data.rename(...)\ .set_index(...)。有些人发现方法调用在视觉上对齐是一种美感。 @jpp:是的,但是太丑了我不知道我是否想去那里;-)【参考方案2】:

请参阅@MartijnPieters' explanation 以解决代码中的错误。

但是,请注意,Pandorable 方法是使用方法链。有些人发现在视觉上对齐方法名称在美学上令人愉悦。这是一个例子:

def rename_n_index(data, col_in='tempus_interval_time', col_out='Timestamp'):

    renamed = data.rename(index=str, columns=col_in: col_out)\
                  .set_index('Timestamp')

    return renamed

然后将这些应用于一系列数据帧,如your previous question:

dfs = [df.pipe(rename_n_index) for df in (df1, df2, df3)]

【讨论】:

以上是关于使用用户定义函数时如何让两个函数返回?的主要内容,如果未能解决你的问题,请参考以下文章

R:如何让用户定义的函数返回多个输出? [复制]

Promise mysql返回未定义,如何让函数等待结果

如何在Python中让两个print函数的输出打印在一行内

如何从用户定义的函数返回 3D 数组?

如何从 SQL 中的用户定义函数返回多个值

函数进阶1