请考虑以下代码段(假设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的好处.我该怎么做呢?特别:
这就是我期望的"正确"解决方案.我想将列的类型从一种类型转换为另一种类型,所以我应该使用强制转换.作为一个上下文,让我提醒您将其转换为另一种类型的正常方法:
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
我正在尝试将我的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/)的目录中搜索包,而不是当前的工作目录.
什么是一种好的,永久性的方法,可以在开发包时轻松运行脚本?
这是一个相关的其他问题(特别是对第一个答案的评论).
到目前为止,我发现的解决方案分为三类,但没有一个是理想的:
mylibsrc到我的PYTHONPATH环境变量.这似乎是最官方的(Pythonic?)解决方案,但意味着每次我检查一个项目时我都要记得在我可以运行其中的任何代码之前手动更改我的环境..到我的PYTHONPATH环境变量的开头.据我了解,这可能会有一些安全问题.如果我是唯一一个使用我的代码的人,这实际上是我最喜欢的技巧,但我不是,我不想让别人这样做.test/我看到了他们所有(间接)包含一行代码的建议sys.path.insert(0, os.path.abspath('..'))(例如,在构建项目时).呸!对于仅用于测试的文件而言,这似乎是一个可以忍受的黑客攻击,而不是那些随软件包一起安装的文件.-m脚本运行脚本,搜索路径在工作目录而不是bin/目录中开始.有关详细信息,请参阅下面的答案.setup.py developlogc答案和pip install -e我的命令.他们避免为每一个小编辑重新"安装",但你仍然需要创建一个setup.py你永远不打算完全安装的包,并且与PyCharm(它有一个菜单项来运行 …假设我在 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.cpp和bar.cpp翻译单元中)但从未在任何地方定义。另一方面,它也没有在任何地方使用。这是合法的吗?我怀疑这在实践中很好,因为编译单元都没有引用foo符号,所以链接器永远不会尝试找到它。但我很好奇 C++ 标准是否保证这没问题。(我什至不确定标准是否讨论了链接。)