python - 评估在命令行上传递的公式
问题描述
我有一个小的(ish)python 脚本,用于绘制 csv 分隔的数据,使用 matplotlib 和 pandas(CSV 被读入 pandas 数据帧)。基本上是重新发明了一个糟糕的 gnuplot 版本。
绘制该进程在标准输出上发出的 csv 数据的典型调用makes_csv
如下:
makes_csv | plot.py --cols 1 3
这意味着“将输入的第 1 列和第 3 列作为单独的系列绘制在第 0 列(标题来自输入数据)”。
现在,我想添加绘制派生列的功能,这是一个引用一个或多个现有列的公式。例如,我可能会写如下内容:
... | plot.py --formula-cols 'foo=col(1)/col(3)*100'
这意味着:绘制将第 1 列中的值除以第 3 列中的相应值乘以 100 的(每个元素)结果,并将该系列称为“foo”。
我不需要上面的确切语法——我想要的主要是基本的数学函数和引用列的能力。我不想重新发明轮子解析公式或使用第三方公式解析:我想使用一些 python 原生方式。
我不担心安全性 - 如果恶意公式可以删除我的硬盘驱动器或破坏我的信用,我可以接受:我自己输入这些公式并且不关心沙盒。
解决方案
答案可能涉及内置函数eval()
和/或exec()
. 但是如果不知道“plot.py”是如何工作的,就很难更具体地回答。例如,您的示例表达式需要能够创建一个新列“Foo”。它还需要访问当前的列,但是我们不知道这些列是如何存储在 plot.py 中的?
这是一种方法的要点:
# csv data stored in a list of rows
data = [
[1, 2, 3],
[2, 4, 6],
[3, 6, 9]
]
# formula from the command line argument
formula = 'row[0]/row[2]*100'
source = f'''
for row in data:
row.append({formula})
'''
exec(src)
source
是一个循环的代码,将公式的值附加到数据表中的每一行。 exec()
执行代码。如果没有其他参数,exec()
则使用当前范围。因此,data
指的是全局列表data
,并且row[0]
在公式中指的是循环变量的第一个元素row
。
修改此示例代码以使用 plot.py 中的数据结构作为练习留给读者。
编辑:在查看 github 上的代码后添加此内容。
因为 plot.py 使用 pandas 来处理 csv 文件,所以这相当容易。只需在命令行中输入 pandas 公式并exec()
在脚本中使用即可执行。例如:
# example DataFrame
df = pd.DataFrame({
'A':[1, 2, 3, 4],
'B':[5, 6, 7, 8],
'C':[9, 0, 1, 2]
})
# formula from the command line
formula = "df['D'] = (df['A'] + df['C']) / df['B']"
# apply the formula
exec(formula)
# result
A B C e
0 1 5 9 2.000000
1 2 6 0 0.333333
2 3 7 1 0.571429
3 4 8 2 0.750000
注意:“公式”可以是任何有效的 python/pandas 代码。
推荐阅读
- perl - 使用 perl 在所有文件中搜索和更新字符串
- .net - 通过 Microsoft Graph API 创建新的 AD B2C 用户
- android - 颤振语音识别语言环境de_DE不起作用
- json - 使用 json serde 在 hive 中加载 json 文件
- amazon-web-services - 最好扩展更少的大型实例还是更多的小型实例?
- ibm-mobilefirst - 问题 - 光标将焦点转移到基于 xcode 10.1 构建的 iOS 12 IPA 上的下一个文本框
- vb.net - 修改水晶报表中的参数值
- java - 如何从比屏幕大的视图的屏幕截图中创建位图?
- python - 为什么当我添加我用作参数的组时,由于 nonetype 没有属性而出现属性错误
- directus - 使用 git 升级 Directus 7 会导致使用时出错 - git pull origin