小编Art*_*cca的帖子

如何将数组(即列表)列转换为Vector

问题的简短版本!

请考虑以下代码段(假设spark已设置为某些代码段SparkSession):

from pyspark.sql import Row
source_data = [
    Row(city="Chicago", temperatures=[-1.0, -2.0, -3.0]),
    Row(city="New York", temperatures=[-7.0, -7.0, -5.0]), 
]
df = spark.createDataFrame(source_data)
Run Code Online (Sandbox Code Playgroud)

请注意,temperature字段是浮动列表.我想将这些浮点数列表转换为MLlib类型Vector,我希望使用基本DataFrameAPI 表示这种转换,而不是通过RDD表达(这是低效的,因为它将所有数据从JVM发送到Python,处理在Python中完成,我们没有得到Spark的Catalyst优化器,yada yada的好处.我该怎么做呢?特别:

  1. 有没有办法让直接演员工作?请参阅下面的详细信息(以及尝试解决方法失败)?或者,是否有其他操作具有我之后的效果?
  2. 从我在下面建议的两种替代解决方案(UDF vs爆炸/重新组合列表中的项目)中哪种更有效?或者是否有其他几乎但不是非常正确的替代品比其中任何一种更好?

直接投射不起作用

这就是我期望的"正确"解决方案.我想将列的类型从一种类型转换为另一种类型,所以我应该使用强制转换.作为一个上下文,让我提醒您将其转换为另一种类型的正常方法:

from pyspark.sql import types
df_with_strings = df.select(
    df["city"], 
    df["temperatures"].cast(types.ArrayType(types.StringType()))),
)
Run Code Online (Sandbox Code Playgroud)

现在例如df_with_strings.collect()[0]["temperatures"][1]'-7.0'.但是如果我施放到ml Vector那么事情就不那么顺利了:

from pyspark.ml.linalg import VectorUDT
df_with_vectors = df.select(df["city"], df["temperatures"].cast(VectorUDT()))
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:

pyspark.sql.utils.AnalysisException: "cannot resolve 'CAST(`temperatures` AS STRUCT<`type`: TINYINT, `size`: INT, `indices`: ARRAY<INT>, `values`: ARRAY<DOUBLE>>)' due to data type …
Run Code Online (Sandbox Code Playgroud)

python apache-spark apache-spark-sql pyspark apache-spark-ml

54
推荐指数
3
解决办法
2万
查看次数

在标准项目目录结构中调用脚本(bin子目录的Python路径)

我正在尝试将我的Python代码放入用于部署的标准目录结构中setup.py,也许是PyPI.对于一个名为mylib的Python库,它将是这样的:

mylibsrc/
  README.rst
  setup.py
  bin/
    some_script.py
  mylib/
    __init.py__
    foo.py
Run Code Online (Sandbox Code Playgroud)

通常还有一个test/子目录,但我还没有尝试编写单元测试.bin/可以在官方Python打包文档中找到在子目录中包含脚本的建议.

当然,脚本的开头代码如下所示:

#!/usr/bin/env python
from mylib.foo import something
something("bar")
Run Code Online (Sandbox Code Playgroud)

当它最终部署脚本(例如devpi)然后用pip安装它时,这很有效.但是,如果我直接从源目录运行脚本,就像我在开发库/脚本的新更改时一样,我收到此错误:

ImportError: No module named 'mylib'
Run Code Online (Sandbox Code Playgroud)

即使当前工作目录是root mylibsrc/并且我通过键入运行脚本也是如此./bin/some_script.py.这是因为Python开始在正在运行的脚本(即from bin/)的目录中搜索包,而不是当前的工作目录.

什么是一种好的,永久性的方法,可以在开发包时轻松运行脚本?

这是一个相关的其他问题(特别是对第一个答案的评论).

到目前为止,我发现的解决方案分为三类,但没有一个是理想的:

  1. 在运行脚本之前,以某种方式手动修复Python的模块搜索路径.
    • 您可以手动添加mylibsrc到我的PYTHONPATH环境变量.这似乎是最官方的(Pythonic?)解决方案,但意味着每次我检查一个项目时我都要记得在我可以运行其中的任何代码之前手动更改我的环境.
    • 添加.到我的PYTHONPATH环境变量的开头.据我了解,这可能会有一些安全问题.如果我是唯一一个使用我的代码的人,这实际上是我最喜欢的技巧,但我不是,我不想让别人这样做.
    • 在互联网上查看答案时,对于目录中的文件,test/我看到了他们所有(间接)包含一行代码的建议sys.path.insert(0, os.path.abspath('..'))(例如,在构建项目时).呸!对于仅用于测试的文件而言,这似乎是一个可以忍受的黑客攻击,而不是那些随软件包一起安装的文件.
    • 编辑:我已经找到了另一种选择,结果就是这个类别:通过使用Python的-m脚本运行脚本,搜索路径在工作目录而不是bin/目录中开始.有关详细信息,请参阅下面的答案.
  2. 在使用之前,使用setup.py(直接运行或使用pip)将软件包安装到虚拟环境中.
    • 如果我只是测试一个我不确定在语法上是否正确的变化,这似乎有些过分.我正在研究的一些项目甚至不打算作为软件包安装,但是我想对所有内容使用相同的目录结构,这意味着编写一个setup.py只是为了测试它们!
    • 编辑:下面的答案中讨论了两个有趣的变体:setup.py developlogc答案和pip install -e我的命令.他们避免为每一个小编辑重新"安装",但你仍然需要创建一个setup.py你永远不打算完全安装的包,并且与PyCharm(它有一个菜单项来运行 …

python setup.py

7
推荐指数
1
解决办法
2013
查看次数

声明但不定义未使用的函数是否合法?

假设我在 C++ 中有以下文件:

// bar.hpp
int foo();
int bar();

// bar.cpp
#include "bar.hpp"
int bar() { return 3; }

// main.cpp
#include "bar.hpp"
int main() { return bar(); }
Run Code Online (Sandbox Code Playgroud)

请注意,foo()已声明(在main.cppbar.cpp翻译单元中)但从未在任何地方定义。另一方面,它也没有在任何地方使用。这是合法的吗?我怀疑这在实践中很好,因为编译单元都没有引用foo符号,所以链接器永远不会尝试找到它。但我很好奇 C++ 标准是否保证这没问题。(我什至不确定标准是否讨论了链接。)

c++ linker one-definition-rule language-lawyer

3
推荐指数
1
解决办法
113
查看次数