Python,使用lambda

时间:2017-12-26 19:05:03

标签: python lambda

我有以下代码声明:

def gigajoule(row):
 row['Energy Supply'] *= 1000000
 return row
energy = energy.apply(gigajoule, axis = 1)

可能应该有一种方法可以通过使用lambda函数来简化,但我无法弄清楚如何做到这一点。

3 个答案:

答案 0 :(得分:2)

lambdas的想法是他们没有做副作用",就是他们只是对输入参数进行操作(检查this answer以获得更详细的答案)

所以可以只返回rowEnergy Supply乘以100万:

gigajoule = lambda row: dict([(k,v*1000000) if k=='Energy Supply' else (k,v) for k,v in row.items()])

并像这样使用它:

>>> row = {'something': 1, 'Energy Supply': 1}
>>> row = gigajoule(row)
>>> row
{'Energy Supply': 1000000, 'something': 1}

但实际上,你的完整功能可以正常工作,而且这个东西更具可读性

答案 1 :(得分:2)

在您的示例代码中,您使用df.apply与正常使用模式不同。正常用法是从提供的数据生成新的值行而不修改原始数据(请参阅.apply() documentation中有关副作用的警告)。这也是lambda函数的行为方式 - 它们通过单行计算生成新值,但无法进行直接赋值。但是,在您的情况下,您正在修改您给定的行,然后返回该行。

请注意,您的代码可能正在执行与您期望的完全不同的操作。它执行以下操作:

  1. gigajoule从数据框
  2. 收到一行
  3. gigajoule修改收到的行,可能会修改原始数据框本身
  4. gigajoule返回修改后的行
  5. pandas将gigajoule返回的行汇编为新的数据帧
  6. 您将现有数据框替换为新数据框。
  7. 第2步非常不标准(将原始数据框修改为apply操作的副作用)。例如,以下代码可能会意外地更改原始energy框架:

    import pandas as pd
    energy = pd.DataFrame({'Energy Supply': [100, 200, 300], 'Temperature': [201, 202, 203]})
    def gigajoule(row):
        row['Energy Supply'] *= 1000000
        return row
    energy2 = energy.apply(gigajoule, axis = 1)
    energy # has been modified!
    

    你可以使用与lambda相同的模式,这样也会以非标准的方式改变原始框架:

    import pandas as pd
    energy = pd.DataFrame({'Energy Supply': [100, 200, 300], 'Temperature': [201, 202, 203]})
    energy2 = energy.apply(
      lambda row: row.set_value('Energy Supply', row['Energy Supply']*1000000), 
      axis=1
    )
    energy # has been modified
    

    您可以使用.copy()来避免原始帧上的非标准副作用,如下所示:

    import pandas as pd
    energy = pd.DataFrame({'Energy Supply': [100, 200, 300], 'Temperature': [201, 202, 203]})
    energy = energy.apply(
      lambda row: row.copy().set_value('Energy Supply', row['Energy Supply']*1000000), 
      axis=1
    )
    

    但是,由于您实际上并没有尝试生成新的数据帧(即,您实际上想要修改现有的数据帧),您可以这样做,这将是使用pandas的最标准方法:< / p>

    import pandas as pd
    energy = pd.DataFrame({'Energy Supply': [100, 200, 300], 'Temperature': [201, 202, 203]})
    energy['Energy Supply'] *= 1000000
    # or energy.loc[:, 'Energy Supply'] *= 1000000
    

    此示例还使用numpy对计算进行矢量化,因此它应该比以前的速度快得多。

答案 2 :(得分:0)

实际上有一种非常简单的方法需要lambda:

energy['Energy Supply'] *= 1000000