🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

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

Q&A

解決済

3回答

5441閲覧

Python 数字に「,(カンマ)」をつける方法、及び小数点の扱い方について

qsuke

総合スコア11

Python

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

0グッド

1クリップ

投稿2019/09/21 16:18

編集2019/09/21 17:09

前提・実現したいこと

日付と数字が混在する表の、数字部分だけに、3桁ごとに仕切りをつける「,(カンマ)」、あるいは小数点の何桁かで四捨五入をするようにしたいです。

困っていること、及び該当のソースコード

ベースとなるのは、以下のようなCSVから読み込んだものを、pd.read_sql_queryを使用してDataFrameに格納したものです。
イメージ説明

これに対して、以下のようにして書式を適用して「,(カンマ)」を付けようとしたのですが、

Python

1df.applymap('{:,}'.format)

以下のようなエラーが発生してしまいました。

Python

1--------------------------------------------------------------------------- 2ValueError Traceback (most recent call last) 3<ipython-input-15-4735cd74c36b> in <module>() 4----> 1 df.applymap('{:,}'.format) 5 6/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in applymap(self, func) 7 5066 return lib.map_infer(x.asobject, func) 8 5067 9-> 5068 return self.apply(infer) 10 5069 11 5070 # ---------------------------------------------------------------------- 12 13/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds) 14 4875 f, axis, 15 4876 reduce=reduce, 16-> 4877 ignore_failures=ignore_failures) 17 4878 else: 18 4879 return self._apply_broadcast(f, axis) 19 20/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in _apply_standard(self, func, axis, ignore_failures, reduce) 21 4971 try: 22 4972 for i, v in enumerate(series_gen): 23-> 4973 results[i] = func(v) 24 4974 keys.append(v.name) 25 4975 except Exception as e: 26 27/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in infer(x) 28 5064 if x.empty: 29 5065 return lib.map_infer(x, func) 30-> 5066 return lib.map_infer(x.asobject, func) 31 5067 32 5068 return self.apply(infer) 33 34pandas/_libs/src/inference.pyx in pandas._libs.lib.map_infer() 35 36ValueError: ("Cannot specify ',' with 's'.", 'occurred at index date')

これを、たとえば
・date以外の数字には3桁ごとに仕切りをつける「,(カンマ)」つけて小数点は非表示
・ただし、histは小数点第3位を四捨五入(小数点第2位まで表示)
とするにはどのような方法がありますでしょうか?

小数点もformatで同様にできると思うのですが、場合分けで適用するやり方が分からず、困ってしまいました。アドバイスいただけると助かります。よろしくお願いします。

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

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

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

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

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

siruku6

2019/09/21 16:53

まずは、発生したエラー内容詳細を掲載いただけないでしょうか? 恐らく、日付の列があるのでそこは少なくともエラーになりそうだとは思っているのですが.... 他にも必要な情報は色々あると思いますが、最低限エラーがないと他の皆さんも回答しにくいと思います
qsuke

2019/09/21 17:10

ご指摘ありがとうございます。 まだあまり勝手が分かっていないものでして、ご指摘いただけて助かりました。 ひとまず、発生したエラーを記載してみました。ご確認のほどよろしくお願いします。
siruku6

2019/09/21 23:23

予想通りでした。 もしかしたら解決できそうなので少々お待ちを、、、その間にほかの方が回答してしまうかもですがw
guest

回答3

0

ベストアンサー

  • df.select_dtypes(include=float)float列のみ抽出
  • histとそれ以外に対して適切にformat

でよいかと思います。
なお、format適用後、値は数値ではなくobject型になることにご注意ください。

Python

1import pandas as pd 2 3# テストデータ 4df = pd.DataFrame({'date':['2019-09-06'], 'close':[2335.0], 'hist':[-24.684088]}) 5df['date'] = pd.to_datetime(df['date']) 6 7for c in df.select_dtypes(include=float).columns: 8 if c == 'hist': 9 df[c] = df[c].apply('{:.2f}'.format) 10 else: 11 df[c] = df[c].apply('{:,.0f}'.format) 12 13print(df) 14# date close hist 15#0 2019-09-06 2,335 -24.68 16 17print(df.dtypes) 18""" 19date datetime64[ns] 20close object 21hist object 22"""

表示形式を指定

すこし面倒ですが、以下のようなコードにより、数値のまま表示形式を変えることもできます。
参考:How to display pandas DataFrame of floats using a format string for columns?

Python

1import pandas as pd 2 3# テストデータ 4df = pd.DataFrame({'date':['2019-09-06'], 'close':[2335.0], 'hist':[-24.684088]}) 5df['date'] = pd.to_datetime(df['date']) 6 7formatters = {} # 列ごとの書式 8for c in df.select_dtypes(include=float).columns: 9 if c == 'hist': 10 formatters[c] = '{:.2f}'.format 11 else: 12 formatters[c] = '{:,.0f}'.format 13 14print(df.to_string(formatters=formatters)) 15# date close hist 16#0 2019-09-06 2,335 -24.68 17 18print(df.dtypes) 19""" 20date datetime64[ns] 21close float64 22hist float64 23"""

投稿2019/09/21 23:34

編集2019/09/22 01:15
can110

総合スコア38341

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

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

qsuke

2019/09/22 02:26

ご丁寧に、詳細な回答をいただきありがとうございました!
guest

0

やりたいことはdataframeを表示したときにカンマ区切りや四捨五入をした状態で表示したいと言うことかと推測しますが、dataframeの中身を改変すると、後々の処理に影響が及んでしまうのでは無いでしょうか?

表示用に値をいじるのは他の方が回答した通りになります。

投稿2019/09/22 01:01

nandymak

総合スコア799

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

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

siruku6

2019/09/22 01:04

確かに、カンマ区切りにしてしまうともう数値としての計算処理はできなさそうでした。 カンマ区切りから元に戻す方法もあるのかもしれませんが、、、面倒ですし、どうせならカンマ区切りデータは別の変数に保存した方がよさそうですね。
guest

0

先にとられたーと思いましたが、私のしようとしていた回答よりも詳しい上に的確な内容に見えましたので、高評価ぽちさせていただきました...
>can110さん

※コメントに書こうとして、間違えて回答欄に書いてしまった...

恥ずかしいので私の回答も載せます

私の方法だと、どの列に対してどの操作をするかを明示する必要があります。

python

1# hist列だけを四捨五入 2df['hist'] = np.round(df['hist'], decimals=2) 3 4# 3桁ごとのカンマ区切りにしたい列だけをカンマ区切りにする 5df[['close', 'volume', 'Market-cap', 'hist']] = \ 6 df[['close', 'volume', 'Market-cap', 'hist']].applymap('{:,}'.format) 7 8# 補足: \ をおくと、そこで改行できる 9 10# 結果表示 11df

投稿2019/09/21 23:56

編集2019/09/22 00:20
siruku6

総合スコア1382

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

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

qsuke

2019/09/22 02:35

ご丁寧にありがとうございます! アドバイスいただいたことで、複数、回答をいただくことができました。 siruku6さんのアドバイスについて、1つ質問させてください。 # 3桁ごとのカンマ区切りにしたい列だけをカンマ区切りにする df[['close', 'volume', 'Market-cap']] = df[['close', 'volume', 'Market-cap']].applymap('{:,}'.format) としたときに、 File "<ipython-input-41-029e46244393>", line 5 dfs[['close', 'volume', 'Market-cap']] = dfs[['close', 'volume', 'Market-cap']].applymap('{:,}'.format)   ^ SyntaxError: invalid character in identifier このようなエラーが出てしまいました。これはどういったことで、どうすれば解消できるのでしょうか?(ひょっとしたら、対象となるデータはたくさんあるので、変換できない形式のデータが混じっている、ということでしょうか?) 小数点のroundの方はうまくできました。ありがとうございます。
siruku6

2019/09/22 02:44 編集

無事解決できたようで何よりです! 【質問について】 SyntaxErrorは、処理中にエラーが起きたのではなくて、コードの書き方の文法が間違っているときに出るエラーです。 掲載していただいたソースコードをよく見ると、 >dfs[['close', 'volume', 'Market-cap']] = dfs[['close', 'volume', 'Market-cap']].applymap('{:,}'.format) のうち、'='の後ろが全角スペースになっているように見えますので、これが原因かなと思いました。 半角スペースに変えてみましょう。 それ以外の場合は、カッコの数が合わないとか、余計なところにカンマがあるとか、変なところで改行をしているとか、そういう理由(文法上の誤り)で出てくるのが`SyntaxError`というやつです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問