python - 在 Python 中减少多个 lamda 表达式
问题描述
我有一系列 lambda 表达式,我觉得它们可以在某些方面有效地减少。我想知道最好的方法是什么。将它们重写为循环或任何好的解决方案?
df = (
df
.assign(
result_1 = lambda x: x['body'].apply(lambda s: function1(s)),
result_2 = lambda x: x['body'].apply(lambda s: function2(s)),
result_3 = lambda x: x['body'].apply(lambda s: function3(s)),
result_4 = lambda x: x['mind'].apply(lambda s: function1(s)),
result_5 = lambda x: x['mind'].apply(lambda s: function2(s)),
result_6 = lambda x: x['mind'].apply(lambda s: function3(s)))
.assign(
A_body_label = lambda x: x['result_1'].apply(lambda s: (s[0]['label'])),
A_body_score = lambda x: x['result_1'].apply(lambda s: (s[0]['score'])),
B_body_label = lambda x: x['result_2'].apply(lambda s: (s[0]['label'])),
B_body_score = lambda x: x['result_2'].apply(lambda s: (s[0]['score'])),
C_body_label = lambda x: x['result_3'].apply(lambda s: (s[0]['label'])),
C_body_score = lambda x: x['result_3'].apply(lambda s: (s[0]['score'])),
A_mind_label = lambda x: x['result_4'].apply(lambda s: (s[0]['label'])),
A_mind_score = lambda x: x['result_4'].apply(lambda s: (s[0]['score'])),
A_mind_label = lambda x: x['result_5'].apply(lambda s: (s[0]['label'])),
A_mind_score = lambda x: x['result_5'].apply(lambda s: (s[0]['score'])),
A_mind_label = lambda x: x['result_6'].apply(lambda s: (s[0]['label'])),
A_smind_score = lambda x: x['result_6'].apply(lambda s: (s[0]['score'])))
解决方案
lambda s: function1(s)
等价于function1
,只是更昂贵,因为首先要调用一个无操作的包装器。
遗憾的是,其他的更难摆脱,因为 Python 不提供对函数组合的内置支持。相反,我会定义生成其他函数的函数。
例如,
def make_result_function(part, f):
return lambda x: x[part].apply(f)
def foo(result, kind):
return lambda x: x[result].apply(lambda s: s[0][kind])
df = (
df
.assign(
result_1=make_result_function("body", function1),
result_2=make_result_function("body", function2),
result_3=make_result_function("body", function3),
result_4=make_result_function("mind", function1),
result_5=make_result_function("mind", function2),
result_6=make_result_function("mind", function3))
.assign(
A_body_label=foo('result_1', 'label'),
A_body_score=foo('result_1', 'score'),
B_body_label=foo('result_2', 'label'),
B_body_score=foo('result_2', 'score'),
C_body_label=foo('result_3', 'label'),
C_body_score=foo('result_3', 'score'),
A_mind_label=foo('result_4', 'label'),
A_mind_score=foo('result_4', 'score'),
B_mind_label=foo('result_5', 'label'),
B_mind_score=foo('result_5', 'score'),
C_mind_label=foo('result_6', 'label'),
C_mind_score=foo('result_6', 'score'),
))
要查看内置组合如何提供帮助,请定义一个函数pipe
:
# This is backwards from normal mathematical composition, where
# compose = lambda f, g: lambda x: f(g(x))
def pipe(f, g):
return lambda x: g(f(x))
我们还将从operator
模块中导入一对函数
from operator import itemgetter, methodcaller
df = (
df
.assign(
result_1=pipe(itemgetter('body'), methodcaller('apply', function1)),
result_2=pipe(itemgetter('body'), methodcaller('apply', function2)),
result_3=pipe(itemgetter('body'), methodcaller('apply', function3)),
result_4=pipe(itemgetter('mind'), methodcaller('apply', function4)),
result_5=pipe(itemgetter('mind'), methodcaller('apply', function5)),
result_6=pipe(itemgetter('mind'), methodcaller('apply', function6)))
.assign(
A_body_label = pipe(itemgetter('result_1'), methodcaller('apply', lambda s: s[0]['label']),
A_body_score = pipe(itemgetter('result_1'], methodcaller('apply', lambda s: s[0]['score'])),
B_body_label = pipe(itemgetter('result_2'), methodcaller('apply', lambda s: s[0]['label'])),
B_body_score = pipe(itemgetter('result_2'], methodcaller('apply', lambda s: s[0]['score'])),
C_body_label = pipe(itemgetter('result_3'), methodcaller('apply', lambda s: s[0]['label'])),
C_body_score = pipe(itemgetter('result_3'], methodcaller('apply', lambda s: s[0]['score'])),
A_mind_label = pipe(itemgetter('result_4'), methodcaller('apply', lambda s: s[0]['label'])),
A_mind_score = pipe(itemgetter('result_4'], methodcaller('apply', lambda s: s[0]['score'])),
B_mind_label = pipe(itemgetter('result_5'), methodcaller('apply', lambda s: s[0]['label'])),
B_mind_score = pipe(itemgetter('result_5'], methodcaller('apply', lambda s: s[0]['score'])),
C_mind_label = pipe(itemgetter('result_6'), methodcaller('apply', lambda s: s[0]['label'])),
C_mind_score = pipe(itemgetter('result_6'], methodcaller('apply', lambda s: s[0]['score']))))
现在考虑用 Coconut 编写的相同作业,Coconut是专为函数式编程设计的 Python 超集。特别是,为使用 , 和我们上面编写的函数提供了特殊itemgetter
的methodcaller
语法pipe
。
df = (
df
.assign(
result_1 = .['body'] |> .apply(function1),
result_2 = .['body'] |> .apply(function2),
result_3 = .['body'] |> .apply(function3),
result_4 = .['mind'] |> .apply(function4),
result_5 = .['mind'] |> .apply(function5),
result_6 = .['mind'] |> .apply(function6))
.assign(
A_body_label = .['result_1'] |> .apply(.[0] |> .['label']),
A_body_score = .['result_1'] |> .apply(.[0] |> .['score']),
B_body_label = .['result_2'] |> .apply(.[0] |> .['label']),
B_body_score = .['result_2'] |> .apply(.[0] |> .['score']),
C_body_label = .['result_3'] |> .apply(.[0] |> .['label']),
C_body_score = .['result_3'] |> .apply(.[0] |> .['score']),
A_mind_label = .['result_4'] |> .apply(.[0] |> .['label']),
A_mind_score = .['result_4'] |> .apply(.[0] |> .['score']),
B_mind_label = .['result_5'] |> .apply(.[0] |> .['label'])
B_mind_score = .['result_5'] |> .apply(.[0] |> .['score']),
C_mind_label = .['result_6'] |> .apply(.[0] |> .['label']),
C_mind_score = .['result_6'] |> .apply(.[0] |> .['score'])))
推荐阅读
- python - 我的回文程序是否正确且有条理?
- css - 使用 webpack 保持文件/文件夹结构将 SCSS 最小化为 CSS
- docker - docker stdin 和 tty 标志如何在容器的幕后工作?
- java - 绘制带和不带着色器的三角形 VBO
- c++ - Validating an NMEA sentence using C++
- nginx - 在 VPS 上以生产模式在 Ubuntu 16.04 LTS 上的 NginX/Passenger 服务器上部署 Flask 应用程序
- python - 在 QTextDocument 中单击链接时生成自定义事件
- jmeter - 我想在循环控制器中使用所有提取的值
- ruby-on-rails - 您正在从