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

时间:2018-07-06 14:41:20

标签: python pandas user-defined-functions

我刚刚开始使用用户定义的函数,所以请原谅这不是一个非常复杂的问题。

我有几个数据框,所有的数据框都有一个名为“ interval_time”的列,例如,我想将此列重命名为“ Timestamp”,然后将此重命名的列设置为索引。

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

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

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分: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)]