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

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

新規登録して質問してみよう
ただいま回答率
85.34%
pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

151閲覧

pandasでセルごとに条件にあった処理をしたい

nomsan

総合スコア5

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

1グッド

0クリップ

投稿2024/12/24 08:06

実現したいこと

python初心者です。いつもお世話になります。よろしくお願いいたします。
pandasでセルの内容に応じて辞書のキーでセルを置換する処理をしたいです。

発生している問題・分からないこと

下記のソースコードで「区分」に辞書「T_d」の該当する値をcolumns「奥行」に入れたいです。
「奥行」には現時点で数値が入っているので「区分」が該当する時のみ値を書き換えたいですが
私が書いたコードでは下記のエラーが発生します。

エラーメッセージ

error

1TypeError: Cannot setitem on a Categorical with a new category (970), set the categories first

該当のソースコード

   品名 区分 奥行 AAAA200QCCCC1 Q 600 AAAA250EBBBB1 E 970 AAAA150DAAAA1 D 970 AAAA200LBBBB2 L 650 AAAA300TVVVV1 T 750 AAAA400RRRRR1 R 650 #(この「奥行」には成功した時の値が入っています) T_d = {"E":970,"D":970,"K":650,"L":650,"P":600,"Q":600,"R":650,"S":650,"T":750,"U":750} for T_k,T_v in T_d.items(): df_a = df_a.mask((df_a["区分"] == T_k),T_v)

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

申し訳ありません。他に方法が思いつかないために他の方法は試していません。

補足

現在は「品名」の8文字目を「区分」に抜き出してその後「奥行」の値を置換しようとしています。
もし「品名」の8文字目と辞書のキーを直接比較して「奥行」の値を置換する簡潔な方法が
あれば同時に教えていただけると大変嬉しいです。

melian👍を押しています

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

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

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

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

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

guest

回答2

0

「該当のソースコード」を一部変更した記述例を下記に示します。

「奥行」には現時点で数値が入っているので「区分」が該当する時のみ値を書き換えたい

という条件も満たしているようです。

Python

1import pandas as pd 2 3pd.set_option('display.unicode.east_asian_width', True) 4 5df = pd.DataFrame([['AAAA200QCCCC1', 1000], 6 ['AAAA250EBBBB1', 1000], 7 ['AAAA150DAAAA1', 1000], 8 ['AAAA200LBBBB2', 1000], 9 ['AAAA300TVVVV1', 1000], 10 ['AAAA400RRRRR1', 1000], 11 ['AAAA500ZZZZZ1', 1000]], 12 columns=['品名', '奥行']) 13 14T_d = {'E':970, 'D':970, 'K':650, 'L':650, 'P':600, 15 'Q':600, 'R':650, 'S':650, 'T':750, 'U':750} 16 17for T_k, T_v in T_d.items(): 18 df['奥行'] = df['奥行'].mask(df['品名'].str[7] == T_k, T_v) 19 20print(df) 21# 品名 奥行 22# 0 AAAA200QCCCC1 600 23# 1 AAAA250EBBBB1 970 24# 2 AAAA150DAAAA1 970 25# 3 AAAA200LBBBB2 650 26# 4 AAAA300TVVVV1 750 27# 5 AAAA400RRRRR1 650 28# 6 AAAA500ZZZZZ1 1000

投稿2024/12/24 13:36

little_street

総合スコア435

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

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

nomsan

2024/12/25 05:37

little_streetさん、回答ありがとうございます。 解決しました。本当にありがとうございます。 ベストアンサー級の回答なのですが、今回は早く回答したいただいた方に ベルトアンサーをつけさせてもらいました。 もし可能ならまた助けていただけると助かります。 よろしくお願いいたします。
guest

0

ベストアンサー

pandas.Series.str アクセサで「品名」の8文字目を抽出して、pandas.Series.map() メソッドで「奥行」に変換するとよいかと思います。(T_d に該当する区分がない場合は書き換えを行いません)

python

1T_d = {"E":970,"D":970,"K":650,"L":650,"P":600,"Q":600,"R":650,"S":650,"T":750,"U":750} 2depth = df['品名'].str[7].map(T_d) 3df.loc[depth.notna(), '奥行'] = depth 4print(df) 5 6# 品名 区分 奥行 7# 0 AAAA200QCCCC1 Q 600 8# 1 AAAA250EBBBB1 E 970 9# 2 AAAA150DAAAA1 D 970 10# 3 AAAA200LBBBB2 L 650 11# 4 AAAA300TVVVV1 T 750 12# 5 AAAA400RRRRR1 R 650

投稿2024/12/24 08:28

編集2024/12/24 14:30
melian

総合スコア20721

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

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

nomsan

2024/12/25 05:35

melianさん、いつも回答ありがとうございます。 解決しました。 mapメソッドを使用するのですね。勉強になります。 もし可能でしたらこれからもお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問