我有以下代码语句:
def gigajoule(row):
row['Energy Supply'] *= 1000000
return row
energy = energy.apply(gigajoule, axis = 1)
可能应该有一种方法可以通过使用 lambda 函数来简化,但我不知道该怎么做。
最佳答案
在您的示例代码中,您使用的 df.apply
与正常使用模式不同。正常用法是在不修改原始数据的情况下从提供的数据生成一行新值(请参阅 .apply() documentation 中关于副作用的警告)。这也是 lambda
函数的行为方式——它们通过单行计算生成新值,但不能直接赋值。但是,在您的情况下,您正在修改给定的行然后返回它。
请注意,您的代码执行的操作可能与您的预期完全不同。它执行以下操作:
gigajoule
从数据帧接收一行gigajoule
修改它收到的行,可能修改原始数据帧本身gigajoule
返回修改后的行- pandas 将
gigajoule
返回的行组装到一个新的数据帧中 - 用新数据框替换现有数据框。
第 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 的最标准方式:
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来向量化计算,所以应该比前面的快很多。
关于Python,lambda 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47982696/