Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算在命令行上传递的公式_Python_Python 3.x_Pandas_Numpy_Argparse - Fatal编程技术网

Python 计算在命令行上传递的公式

Python 计算在命令行上传递的公式,python,python-3.x,pandas,numpy,argparse,Python,Python 3.x,Pandas,Numpy,Argparse,我有一个小的(ish)python脚本,我使用matplotlib和pandas(csv被读入pandas数据框)来绘制csv分隔的数据。基本上是重新发明了一个糟糕的gnuplot版本 通过进程绘制stdout上发出的csv数据的典型调用如下所示: makes_csv | plot.py --cols 1 3 这意味着“将输入的第1列和第3列作为单独的系列绘制在第0列上(标题来自输入数据)” 现在,我想添加绘制派生列的功能,这是一个引用一个或多个现有列的公式。例如,我可能会写这样的东西: ..

我有一个小的(ish)python脚本,我使用matplotlib和pandas(csv被读入pandas数据框)来绘制csv分隔的数据。基本上是重新发明了一个糟糕的gnuplot版本

通过进程
绘制stdout上发出的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中的数据结构将留给读者作为练习

Edit:在查看github上的代码后添加此项。

因为plot.py使用pandas来处理csv文件,所以这相当容易。只需在命令行中输入一个公式,并在脚本中使用
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代码。

您可能需要引用
foo
参数,以确保shell不会对空格的特殊字符进行任何有趣的操作。关于
argparse
,您将只得到一个字符串值。e、 g.
args.foo=“col(1)…”
eval(args.foo)`可以做你想做的事情,但是从简单而明显的例子开始。编写类似这样的代码,然后在遇到问题时/如果遇到问题,返回一个新问题。在这一点上,你的问题有点没有定论。@hpaulj-谢谢,我引用了foo参数以避免它被shell解释。谢谢。你是对的,我应该包括我的绘图程序的精简版本,但它比我想在问题中包括的要复杂一些。这里有一个问题,我将在某个时候用一个较小的版本更新这个问题。基于github链接上的代码,我添加了一个如何使用pandas的示例。