3.1.python_print()/input()

本文详细介绍了Python中的print()函数,包括其参数、字符串拼接、格式化输出等,并探讨了单引号、双引号和三引号的使用。同时,文章讲解了input()函数的功能,如何设置输入提示以及处理输入值的方法。

環境:python 3.10_amd64 + Win10

1.print()函數

1.1print()函數的參數

value, ..., 表示待打印的對象, 數量可變; 其餘四个爲默認參數:

sep表示多个值之間的間隔符, 默認爲空格' '

end表示打印最後一个值後的添加的字符, 默認爲換行符'\n'

file表示文件對象, 即打印的位置, 默認爲標準輸出流(也就是屏幕)

flush表示是否刷新輸出流, 默認爲False, 不刷新

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

1.2.拼接字符串打印, 注意轉換數值類型, 使用str()函數

>>> print('我有' + 4 + '隻貓.')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    print('我有' + 4 + '隻貓.')
TypeError: can only concatenate str (not "int") to str
>>> print('我有' + str(4) + '隻貓.')
我有4隻貓.

1.3.格式化輸出

1. 可以使用字符串對象的format()方法格式化輸出, 多个{}依次對應format()中的實參:

>>> print('我有{}隻貓, 其中{}隻是貓妹妹. 它們都很可愛!'.format(4, 3))
我有4隻貓, 其中3隻是貓妹妹. 它們都很可愛!

2. 使用f格式化輸出, 在字符串之前加一个f, 字符串內部使用{var_}的形式指明變量, 更直觀簡明, 而且這種格式還有一个方便的地方是, 對于數值類型變量, 不必使用str()函數進行轉換:

>>> name = '自五'
>>> mean = '漢心丹青'
>>> print(f'他怕是很難意識到自己是一个{name}, 因此發表意見時向來坦蕩, 總叫囂{mean}之類的.')
他怕是很難意識到自己是一个自五, 因此發表意見時向來坦蕩, 總叫囂漢心丹青之類的.

3. 使用類似于C語言的佔位符%格式

python的格式化佔位符比C簡化很多, 常用如下:

%d整數
%o八進制形式
%x 或 %X小寫或大寫十六進制
%e 或 %E小寫或大寫科學計數法表示的浮點數
%f浮點數
%s字符串
%%在使用佔位符的語句中表示%本身

這種形式便于直接控制輸出浮點數的精度:

# 使用%.nf的格式限定浮點數輸出精度
>>> pi = 3.141592653
>>> print('pi = %f'%pi)
pi = 3.141593
>>> print('pi = %.4f'%pi)
pi = 3.1416
>>> print('pi = %.2f'%pi)
pi = 3.14

當有多个變量同時輸出時, 注意變量名的排列順序和格式(以元組形式排列):

>>> a, b, c = 13, 20.5, '三毛'
>>> print('他的名字叫%s, 今年%d歲, 口袋裡面有%.1f元錢.'%(c, a, b))
他的名字叫三毛, 今年13歲, 口袋裡面有20.5元錢.

1.4.引號的使用

單/雙引號在大多數時候作用相同, 當在文本中需要輸出引號時, 可以混用兩者來實現:

>>> print('單/雙引號混用: "我渴了!", 她說.')
單/雙引號混用: "我渴了!", 她說.

1.5.三引號'''的使用

>>> print('''三引號的作用是包含大段文字, 在結束的三引號之前可以任意換行,
    比如這是第二行,
    比如這是第三行,
    在最後一行使用三引號結束文本.''')
三引號的作用是包含大段文字, 在結束的三引號之前可以任意換行,
比如這是第二行,
比如這是第三行,
在最後一行使用三引號結束文本.

1.6.多次重復打印字符串, 使用乘號*

>>> print('Hello\n'*3)
Hello
Hello
Hello

1.7.修改默認參數值, 控制輸出格式

比如設定多个輸出值之間的間隔符爲換行, 更改參數sep='\n':

>>>print('  *', ' * *', '* * *', '  |', sep='\n')
  *
 * *
* * *
  |


2.input()

2.1.input()函數的參數

input()函數的參數爲字符串, 通常作爲輸入提示(prompt), 提示用戶要輸入的類型等, 這條提示會顯示在終端, 然後讀入數據存儲到指定的變量中.

message = input("請輸入留言:")

2.2.處理input()函數的返回值

使用input()讀入的類型爲str, 即字符串類型, 必要時可進行格式轉換, 如下:

gongzi = int(input("請輸入你的工資:"))  # 使用int()將讀入的字符串格式的數值轉換爲整型

age = int(input("請輸入你的年齡:"))
if age >= 18:
    print("原來你是成年人啊!")

money = float(input("請輸入你的月收入:"))
if money >= 10000.0:
    print(str(money) + "You have a good job!")
else:
    print(str(money) + "You are poor...")

也可使用eval()函數, 在確定要讀取數值時調用, 在輸入不可求值的算式時報錯, 如下:

>>> eval(input('請輸入一个數值:'))
>>> 請輸入一个數值:58*22.5-123
1182.0

>>> eval('dsd')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    eval('n')
  File "<string>", line 1, in <module>
NameError: name 'dsd' is not defined
from dask_yarn import YarnCluster from dask.distributed import Client, get_worker from distributed.protocol import serialize, deserialize import pandas as pd from pandas.core.arrays.string_ import StringDtype import dask.dataframe as dd import dask # 设置client环境变量 import os os.environ[ &#39;HADOOP_CONF_DIR&#39;] = &#39;/home/finance/App/jupyter-ide-tech.msxf.lo/.IDE/work/user_data/train_sdk/test/dask/dask_hadoop_conf_new/&#39; os.environ[&#39;PATH&#39;] = os.environ[&#39;PATH&#39;] + &#39;:/opt/cloudera/parcels/CDH/bin/&#39; os.environ[&#39;HADOOP_HOME&#39;] = &#39;/opt/jupyter/3.1.5.0-152/hadoop/&#39; os.environ[&#39;LD_LIBRARY_PATH&#39;] = &#39;/opt/jupyter/3.1.5.0-152/hadoop/lib/native&#39; os.environ[ &#39;CLASSPATH&#39;] = &#39;/opt/jupyter/3.1.5.0-152/hadoop/lib/*:/opt/jupyter/3.1.5.0-152/hadoop/.//*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/./:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/.//*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/.//*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/./:/opt/jupyter/3.1.5.0-152/hadoop-yarn/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/lib/*:/usr/hdp/3.1.5.0-152/hadoop/.//*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/./:/usr/hdp/3.1.5.0-152/hadoop-hdfs/lib/*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/.//*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/lib/*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/.//*:/usr/hdp/3.1.5.0-152/hadoop-yarn/./:/usr/hdp/3.1.5.0-152/hadoop-yarn/lib/*:/usr/hdp/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/conf:/home/finance/App/jupyter-ide-tech.msxf.lo/.IDE/work/user_data/train_sdk/test/dask/dask_hadoop_conf/&#39; def set_scheduler_env(): os.environ[ &#39;CLASSPATH&#39;] = &#39;/opt/jupyter/3.1.5.0-152/hadoop/lib/*:/opt/jupyter/3.1.5.0-152/hadoop/.//*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/./:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/.//*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/.//*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/./:/opt/jupyter/3.1.5.0-152/hadoop-yarn/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/lib/*:/usr/hdp/3.1.5.0-152/hadoop/.//*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/./:/usr/hdp/3.1.5.0-152/hadoop-hdfs/lib/*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/.//*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/lib/*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/.//*:/usr/hdp/3.1.5.0-152/hadoop-yarn/./:/usr/hdp/3.1.5.0-152/hadoop-yarn/lib/*:/usr/hdp/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/conf:/home/finance/App/jupyter-ide-tech.msxf.lo/.IDE/work/user_data/train_sdk/test/dask/dask_hadoop_conf/&#39; # os.environ[&#39;DASK_DISTRIBUTED__DASHBOARD__PORT&#39;] = &#39;8042&#39; return f"环境已设置: {os.environ[&#39;CLASSPATH&#39;]}" # 配置使用 msgpack 序列化 dask.config.set({&#39;distributed.scheduler.worker-ttl&#39;: None}) dask.config.set({&#39;distributed.comm.serialize&#39;: &#39;msgpack&#39;}) # 或者使用 pickle5 dask.config.set({&#39;distributed.comm.serialize&#39;: &#39;pickle5&#39;}) import pandas as pd from pandas.core.arrays.string_ import StringDtype import cloudpickle def apply_compat_patch(): """应用兼容性补丁""" if not hasattr(YarnCluster, &#39;status&#39;): def status(self): try: return self._state except AttributeError: return getattr(self, &#39;_status&#39;, &#39;running&#39;) YarnCluster.status = property(status) apply_compat_patch() def patch_string_dtype(): """ 修复 StringDtype 对象缺少 _na_value 属性的问题 """ # 获取原始的 StringDtype 类 original_string_dtype = StringDtype # 定义补丁后的 StringDtype 类 class PatchedStringDtype(StringDtype): @property def na_value(self): # 直接返回 NA 值,而不是尝试获取 _na_value 属性 return self._na_value def __reduce__(self): # 确保在 pickling 时不会尝试获取 _na_value 属性 return StringDtype, (self.storage, self.na_value) # 替换原始的 StringDtype 类 pd.core.arrays.string_.StringDtype = PatchedStringDtype # 确保 cloudpickle 能够正确处理补丁后的类 cloudpickle.dumps(StringDtype) # 应用补丁 patch_string_dtype() def process_features(df, expr_list): """处理特征列,将_NAL1结尾的值替换为NaN""" for col in expr_list: df[col] = df[col].mask(df[col].astype(str).str.endswith(&#39;_NAL1&#39;), np.nan) return df # 创建集群连接 cluster = YarnCluster( environment=&#39;/home/finance/App/jupyter-ide-tech.msxf.lo/.IDE/work/user_data/dask/dask-yarn-py311-env.tar.gz&#39;, # 打包的环境 # dashboard_address=&#39;:8042&#39;, worker_vcores=4, worker_memory=&#39;12GiB&#39;, scheduler_memory=&#39;12GiB&#39;, scheduler_vcores=1, n_workers=2, deploy_mode=&#39;remote&#39;, # 关键:连接到现有集群 name=&#39;dask-on-yarn-py11-4000&#39;, queue=&#39;root.dask.poc&#39;, worker_env={ "DASK_DISTRIBUTED__LOGGING__DISTRIBUTED": "INFO", "DASK_DISTRIBUTED__LOGGING__BOKEH": "INFO", "DASK_DISTRIBUTED__LOGGING__TUPL": "INFO", "DASK_DISTRIBUTED__ADMIN__LOG_FORMAT": "%(asctime)s %(name)s %(levelname)s %(message)s", "LD_LIBRARY_PATH": "/usr/hdp/current/hadoop-client/lib/native", "HADOOP_HOME": "/usr/hdp/current/hadoop-client", "ARROW_LIBHDFS_DIR": "/usr/hdp/current/hadoop-client/lib/native", &#39;CLASSPATH&#39;: &#39;/opt/jupyter/3.1.5.0-152/hadoop/lib/*:/opt/jupyter/3.1.5.0-152/hadoop/.//*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/./:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-hdfs/.//*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-mapreduce/.//*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/./:/opt/jupyter/3.1.5.0-152/hadoop-yarn/lib/*:/opt/jupyter/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/lib/*:/usr/hdp/3.1.5.0-152/hadoop/.//*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/./:/usr/hdp/3.1.5.0-152/hadoop-hdfs/lib/*:/usr/hdp/3.1.5.0-152/hadoop-hdfs/.//*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/lib/*:/usr/hdp/3.1.5.0-152/hadoop-mapreduce/.//*:/usr/hdp/3.1.5.0-152/hadoop-yarn/./:/usr/hdp/3.1.5.0-152/hadoop-yarn/lib/*:/usr/hdp/3.1.5.0-152/hadoop-yarn/.//*:/usr/hdp/3.1.5.0-152/hadoop/conf:/home/finance/App/jupyter-ide-tech.msxf.lo/.IDE/work/user_data/train_sdk/test/dask/dask_hadoop_conf/&#39;, "HADOOP_CONF_DIR": "/usr/hdp/current/hadoop-client/etc/hadoop/conf", "ARROW_DISABLE_MEMORY_POOL": "false", "PYARROW_JEMALLOC": "true", "OMP_NUM_THREADS": "1", # 禁用OpenMP并行 "MKL_NUM_THREADS": "1" # 禁用MKL并行 # "MALLOC_ARENA_MAX": "2" # 限制内存分配区域 } ) # 扩展集群 # cluster.scale(20) # 扩展到20个worker # 连接客户端 client = Client(cluster) #client.run(patch_string_dtype) client.get_versions(check=True) client.run_on_scheduler(set_scheduler_env) def process_parquet(input_path, output_path): # 读取Parquet文件 df = dd.read_parquet(input_path) # 数据处理示例:筛选非空记录 processed_df = df.dropna() # 写入新Parquet文件 processed_df.to_parquet(output_path) return f"Processed {input_path} to {output_path}" # 加载数据集 try: # 3. 读取HDFS Parquet文件 hdfs_path = "hdfs://ms-n-dlake/user/yonglang.liu/tmp/5-fold/data/part-01499-ea197b0d-57cd-48a6-ba39-382342983409-c000.snappy.parquet" ddf = dd.read_parquet(hdfs_path, engine=&#39;pyarrow&#39;, storage_options={"use_ssl": False}, blocksize=&#39;256MB&#39;) # 7. 保存处理结果 output_path = "hdfs://ms-n-dlake/user/junyao.yao/tmp/5-fold/data/part-01499-ea197b0d-57cd-48a6-ba39-382342983409-c002.snappy.parquet" ddf.to_parquet(output_path,engine=&#39;pyarrow&#39;) finally: print("结束") #client.close() #cluster.shutdown() 这个代码报错,请分析调整下这个代码
08-28
### 问题分析 在使用 Dask 与 YARN 集成处理 HDFS 上的 Parquet 文件时,出现 `OSError: [Errno 255]` 错误,通常表示在尝试访问 HDFS 文件系统时遇到了底层通信或认证问题。该错误可能由多种原因引起,包括 Hadoop 配置缺失、Kerberos 认证失败、文件路径权限不足或 PyArrow 与 HDFS 交互时的序列化异常。 根据 Dask 的使用方式,当处理超大数据集时,可以借助其分布式计算能力将任务分配到多个节点上执行,以缓解内存压力[^1]。然而,当涉及 HDFS 写入操作时,必须确保底层文件系统接口(如 `pyarrow.fs` 或 `hdfs3`)能够正确识别并连接到 HDFS 集群。 ### 配置调整建议 #### 1. 确保 Hadoop 配置文件可用 Dask 依赖于 Hadoop 配置文件(如 `core-site.xml` 和 `hdfs-site.xml`)来正确连接 HDFS。这些文件应放置在运行任务的节点上,并可通过环境变量 `HADOOP_CONF_DIR` 或 `ARROW_HDFS_CONF` 指定路径。 ```python import os os.environ[&#39;HADOOP_CONF_DIR&#39;] = &#39;/path/to/hadoop/conf&#39; ``` #### 2. 使用 Kerberos 认证(如适用) 如果 HDFS 启用了 Kerberos 安全认证,需在连接时提供 Kerberos principal 和 keytab 文件路径: ```python from dask.distributed import Client client = Client(n_workers=4, memory_limit=&#39;32GB&#39;) import pyarrow as pa fs = pa.fs.HadoopFileSystem(host=&#39;namenode&#39;, port=8020, driver=&#39;libhdfs3&#39;, user=&#39;your_kerberos_principal&#39;, kerberos_ticket_cache_path=&#39;/tmp/krb5cc_1234&#39;) ``` #### 3. 设置 Dask Worker 内存限制 为避免内存溢出问题,应在初始化 Dask Client 时设置合理的内存限制: ```python from dask.distributed import Client client = Client(memory_limit=&#39;32GB&#39;) # 每个 worker 的内存限制 [^3] ``` #### 4. 使用 PyArrow 引擎写入 Parquet 文件 为确保数据写入过程的稳定性,建议显式指定 `engine=&#39;pyarrow&#39;` 并避免使用默认引擎,以减少序列化兼容性问题: ```python import dask.dataframe as dd ddf = dd.from_pandas(df, npartitions=2) ddf.to_parquet(&#39;hdfs://namenode/path/to/output&#39;, engine=&#39;pyarrow&#39;) ``` #### 5. 验证写入路径权限 确保运行任务的用户具有对目标 HDFS 路径的写入权限。可以通过 HDFS CLI 检查并修改权限: ```bash hadoop fs -chmod -R 777 /user/junyao.yao/output_path ``` #### 6. 使用 PyArrow 直接写入 若问题仍与 Dask 抽象层相关,可尝试使用 PyArrow 的底层 API 直接写入 Parquet 文件,以绕过 Dask 的调度机制: ```python import pyarrow.parquet as pq import pyarrow as pa table = pa.Table.from_pandas(df) pq.write_table(table, &#39;hdfs://namenode/path/to/output/file.parquet&#39;) ``` --- ### 代码修复示例 结合上述配置调整,以下是一个完整的代码示例,用于在 Dask 与 YARN 集成环境下正确写入 HDFS 上的 Parquet 文件: ```python import os from dask.distributed import Client import dask.dataframe as dd import pyarrow.parquet as pq import pandas as pd # 设置 Hadoop 配置路径 os.environ[&#39;HADOOP_CONF_DIR&#39;] = &#39;/path/to/hadoop/conf&#39; # 初始化 Dask Client 并设置 worker 内存限制 client = Client(memory_limit=&#39;32GB&#39;) # 创建示例 DataFrame df = pd.DataFrame({&#39;id&#39;: range(100000), &#39;value&#39;: [&#39;test&#39;] * 100000}) # 转换为 Dask DataFrame ddf = dd.from_pandas(df, npartitions=4) # 显式使用 PyArrow 引擎写入 HDFS 上的 Parquet 文件 output_path = "hdfs://namenode/path/to/output" ddf.to_parquet(output_path, engine=&#39;pyarrow&#39;) ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值