質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2169閲覧

Pythonで、数値が inf となる場合は代わりに文字列へ変換したい

mtomsy

総合スコア6

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2021/09/15 08:55

前提・実現したいこと

Pythonでyamlファイルを一度読み込み、別のyamlファイルとして書き出す処理を実装しようとしています。
元ファイルの中身を維持しながら別ファイルへ書き出したいのですが、Pythonで該当のyamlファイルを読み込むと一部の値がinfと判定されてしまいます。
該当の値を数値として利用することはないため、yamlファイルをloadする際、inf判定の代わりに文字列へ変換するような方法についてアドバイスをいただきたいです。

環境

Python 3.6.8
ruamel.yaml 0.17.16

発生している問題・エラーメッセージ

inf な値を含む example_in.yaml を Python で load すると、該当の値が inf に変換されてしまう。

該当のソースコード

example_in.yaml

yaml

1hoge: 1e1000

example.py

Python3

1from ruamel.yaml import YAML 2yaml = YAML() 3 4with open("example_in.yaml", 'rt') as f: 5 data = yaml.load(f) 6 7print(data) 8# ordereddict([('hoge', inf)]) 9 10with open("example_out.yaml", 'w') as f: 11 yaml.dump(data, f)

example_out.yaml

yaml

1hoge: .inf

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

力技にはなりますが、inf判定される値をbaseloaderでloadした値に置き換えることで、該当の値のみを文字列にすることができ、無事回避できました。

yaml

1hoge: 1e1000

Python3

1from ruamel.yaml import YAML 2import math 3 4with open("example_in.yaml", 'rt') as f: 5 data = YAML().load(f) 6 7with open("example_in.yaml", 'rt') as f: 8 data_baseloaded = YAML(typ="base").load(f) 9 10for d in data: 11 if data[d] == math.inf: 12 data[d] = data_baseloaded[d] 13 14with open("example_out.yaml", 'w') as f: 15 YAML().dump(data, f)

yaml

1hoge: '1e1000'

皆さまご助力いただきありがとうございました。

投稿2021/09/16 11:06

mtomsy

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

対策

まだ途中ですが、読み込んだ時にYAMLのFLOATでINFの時に、何行目かを出せるとこまで来ました。
あとはその行数の時に力業で値をSTRINGに差し替えればいけそうな気がします。

YAML

1hoge: 1e1000 2hoge1: 1e2

Python3

1from ruamel.yaml import YAML 2import ruamel.yaml 3yaml = YAML() 4 5with open("example_in.yaml", 'rt') as f: 6 data = yaml.load(f) 7 8# print(data) 9# ordereddict([('hoge', inf)]) 10 11for i,d in enumerate(data): 12 if (type(data[d]) == ruamel.yaml.scalarfloat.ScalarFloat) and (str(data[d]) == "inf"): 13 print("[INF DETECTED!] Line:",i, "INDEDX:",d) 14 else: 15 print(d,data[d]) 16 17 18# with open("example_out.yaml", 'w') as f: 19# yaml.dump(data, f) 20

駄目な投稿

yamlファイルをloadする際、inf判定の代わりに文字列へ変換する

"yaml.load" infinityと探していたら偶然見つかりました

YAMLモジュール内の正規表現のせいでそうなっているそうです。
走らせてませんので確認はできていませんが、これで解決できそうな気がします。

投稿2021/09/15 09:55

編集2021/09/15 14:34
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2021/09/15 10:04

いや、たぶん、違うと思います。 「1e1000」はpythonのfloatの上限(1.7976931348623157e+308)を超えてしまうので、inf (無限大)という「値」になってしまうのだと思います。
退会済みユーザー

退会済みユーザー

2021/09/15 14:37 編集

そうですね、その通りと思います。しかも元の英文のタイトルは数値がSTRINGで困っているからFLOATにしてくれ的な内容なので真逆でしたね…。
mtomsy

2021/09/16 09:34

ご返答ありがとうございます。 いただいた対策にアイデアを貰い、infになる値を文字列へ置換することで無事解決に至りそうです。 非常に助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問