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

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

ただいまの
回答率

88.62%

object型からint型に変換したいが''のせいでできない?

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 810

Pablito

score 61

前提・実現したいこと

object型でインポートされたデータフレームの中の値を
全てint型にしたいと思っております。

しかし、数値が''で囲まれているようで、
.replace("''", '')で対処しようとしたのですが、
中々うまくいきません。

下記はデータの一部です。

    months    total    organic    guests
0    Jan    1,021,069    561,101    103,929

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

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-b66f6148172e> in <module>
      1 df = df.replace("''", '')
----> 2 df = df.astype(int)
      3 df.info()

c:\users\lib\site-packages\pandas\core\generic.py in astype(self, dtype, copy, errors)
   5695         else:
   5696             # else, only a single dtype is given
-> 5697             new_data = self._data.astype(dtype=dtype, copy=copy, errors=errors)
   5698             return self._constructor(new_data).__finalize__(self)
   5699 

c:\users\lib\site-packages\pandas\core\internals\managers.py in astype(self, dtype, copy, errors)
    580 
    581     def astype(self, dtype, copy: bool = False, errors: str = "raise"):
--> 582         return self.apply("astype", dtype=dtype, copy=copy, errors=errors)
    583 
    584     def convert(self, **kwargs):

c:\users\lib\site-packages\pandas\core\internals\managers.py in apply(self, f, filter, **kwargs)
    440                 applied = b.apply(f, **kwargs)
    441             else:
--> 442                 applied = getattr(b, f)(**kwargs)
    443             result_blocks = _extend_blocks(applied, result_blocks)
    444 

c:\users\lib\site-packages\pandas\core\internals\blocks.py in astype(self, dtype, copy, errors)
    623             vals1d = values.ravel()
    624             try:
--> 625                 values = astype_nansafe(vals1d, dtype, copy=True)
    626             except (ValueError, TypeError):
    627                 # e.g. astype_nansafe can fail on object-dtype of strings

c:\users\lib\site-packages\pandas\core\dtypes\cast.py in astype_nansafe(arr, dtype, copy, skipna)
    872         # work around NumPy brokenness, #1987
    873         if np.issubdtype(dtype.type, np.integer):
--> 874             return lib.astype_intsafe(arr.ravel(), dtype).reshape(arr.shape)
    875 
    876         # if we have a datetime/timedelta array of objects

pandas\_libs\lib.pyx in pandas._libs.lib.astype_intsafe()
ValueError: invalid literal for int() with base 10: '1,021,069'

該当のソースコード

data = pd.read_csv(path, sep=',')
data.info()
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13 entries, 0 to 12
Data columns (total 4 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   months   13 non-null     object
 1   total    13 non-null     object
 2   organic  13 non-null     object
 3   guests   13 non-null     object
dtypes: object(4)
memory usage: 272.0+ bytes
"""
df = data.drop('months', axis=1)
df = df.replace("''", '')
df = df.astype(int)
df.info()

何卒宜しくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

ValueError: invalid literal for int() with base 10: '1,021,069'とのことなので、カンマ,が含まれているのが原因ですのでreplace(',','', regex=True)のようにしてください。
なお、文字列の一部を置換したいのでregex=Trueが必要です。
指定しないと,という値と完全一致するセル値しか置換されません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/06 19:26

    DataFrame.replace() で正規表現の文字列置換が行えたのですね。
    完全一致だけかと思ってました。

    キャンセル

  • 2020/02/06 19:33

    置換されないので「なんで?」と思ってマニュアル確認したら載ってました。一括処理できるので便利ですね。

    キャンセル

+1

df.replace() は要素の値を入れ替える(完全一致で入れ替わる)為のものなので、文字列の一部を置き換える用途には使えません。

今回のように文字列の一部を置き換えるためには Series.str.replace() を使用してください。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.replace.html

ただこれは DataFrameではなくSeries に対するMethodですので、DataFreme.apply() 等で列毎に適用する必要がありますので

df = df.apply(lambda d: d.str.replace(',', '')).astype(int)


のように記述する必要があります。
ということで上記の方法で ','を削除した後に astype(int)を行うとよいのではないでしょうか。

動作確認

import pandas as pd
df = pd.DataFrame([['Jan','1,021,069','561,101','103,929']],
                  columns = ['months','total','organic','guests'])

df = df.drop('months', axis=1)
df = df.apply(lambda d: d.str.replace(',', '')).astype(int)

print(df)
#     total  organic  guests
#0  1021069   561101  103929

df.info()
#<class 'pandas.core.frame.DataFrame'>
#RangeIndex: 1 entries, 0 to 0
#Data columns (total 3 columns):
# #   Column   Non-Null Count  Dtype
#---  ------   --------------  -----
# 0   total    1 non-null      int64
# 1   organic  1 non-null      int64
# 2   guests   1 non-null      int64
#dtypes: int64(3)
#memory usage: 152.0 bytes

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る