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

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

詳細はこちら
Python

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

Q&A

解決済

4回答

1882閲覧

DataFrame  行内の比較、データの置き換え方法(np.where と loc)

kumatakun

総合スコア7

Python

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

0グッド

0クリップ

投稿2021/02/24 22:36

python 初心者です。
下記のようなデータを読み込み、
行ごとに A列とB列の絶対値を比較し、大きい方を残し、小さい方をゼロにすることを考えております

<入力>
A B
5 -6
7 -2
9 -11
10 -5

<出力>
A  B
0  -6
7  0
0  -11
10  0

np.where で置き換えを考えました。
また、np.where だと typeがobjectになるので数値として扱いたいためastypeで置き換えをしてます

df['A']=np.where(df['A']>((-1)*df['B']),df['A'],'0') df['A']=df['A'].astype(np.float) df['B']=np.where(df['B']<((-1)*df['A']),df['B'],'0') df['B']=df['B'].astype(np.float)

上記でプログラムは動くのですが、警告メッセージが出てきます。

<警告> 0224.py:47: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead

改良を考えているのですが、loc をどのように使えばよいかわからず、アドバイスをいただけると幸いです。

よろしくお願いいたします。

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

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

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

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

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

ppaul

2021/02/25 00:35

A==-Bの時には、kumatakunさんが(たぶん)期待する答えにはならないですね。 たとえば、 A B 5 -5 なら A B 0 -5 となります。
guest

回答4

0

dtypeがobjectになるのは、np.whereで'0'と文字列で置き換えているからです。数値の0と置き換えたらいいです。

また、ここにあるコードの部分だけでは、SettingWithCopyWarningは出ないはずです。
例えば、このdfが別のデータフレームから抜き出したものだったりすると、この警告が出ることもあります。

python

1df = pd.DataFrame({'A': [5, 7, 9, 10], 'B': [-6, -2, -11, -5]}) 2df['A'] = np.where(df['A'] > -df['B'], df['A'], 0)

だと警告は出ませんが、

python

1df0 = pd.DataFrame({'A': [5, 7, 9, 10, 100], 'B': [-6, -2, -11, -5, -100]}) 2df = df0[:4] 3df['A'] = np.where(df['A'] > -df['B'], df['A'], 0)

だと警告が出ます。
理由は警告に出てくるリンク先https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copyを見るか、SettingWithCopyWarningで検索すれば説明しているところがいろいろ見つかると思います。

警告を消す一番簡単な方法は、コピーしてしまうことですが、大元のデータフレーム(上の例のdf0)を更新したいケースでは、正しい対処法ではないです。

python

1df = df.copy() 2flg = df['A'] > -df['B'] 3df['A'] = np.where(flg, df['A'], 0) 4df['B'] = np.whare(~flg, df['B'], 0)

投稿2021/02/24 23:08

編集2021/02/25 07:49
bsdfan

総合スコア4794

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

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

kumatakun

2021/02/25 12:07

ありがとうございます。 大変参考になりました。消去方法ありがとうございます。
guest

0

(参考)

numpy.put_along_axis — NumPy v1.20 Manual

python

1In [1]: import pandas as pd 2 : df = pd.DataFrame({'A': [5, 7, 9, 10], 'B': [-6, -2, -11, -5]}) 3 : df 4 A B 50 5 -6 61 7 -2 72 9 -11 83 10 -5 9 10In [2]: import numpy as np 11 : np.put_along_axis(df.to_numpy(), (df['A'].abs() > df['B'].abs()).to_numpy(int)[:,None], 0, axis=1) 12 13In [3]: df 14Out[3]: 15 A B 160 0 -6 171 7 0 182 0 -11 193 10 0

投稿2021/02/25 05:21

kirara0048

総合スコア1399

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

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

kumatakun

2021/02/25 12:08

ありがとうございます。 わかりやすいコード大変助かります。 またよろしくお願いいたします。
guest

0

ベストアンサー

質問の方にコメントしましたがAが-Bに等しいときどうするかという問題があります。
これを解決するには、元のデータフレームを書き換えるのでは難しいです。

元のデータフレームと別に作るなら以下の方法があります。

python

1>>> print(df) 2 A B 30 5 -6 41 7 -2 52 9 -11 63 10 -5 74 7 -7 8>>> #A=-Bのとき、両方残す 9>>> df2 = pd.concat([df['A'].where(df['A']>=-df['B'],0), df['B'].where(df['A']<=-df['B'],0)], axis=1) 10>>> print(df2) 11 A B 120 0 -6 131 7 0 142 0 -11 153 10 0 164 7 -7 17>>> #A=-Bのとき、両方0にする 18>>> df3 = pd.concat([df['A'].where(df['A']>-df['B'],0), df['B'].where(df['A']<-df['B'],0)], axis=1) 19>>> print(df3) 20 A B 210 0 -6 221 7 0 232 0 -11 243 10 0 254 0 0

投稿2021/02/25 00:52

ppaul

総合スコア24670

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

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

kumatakun

2021/02/25 12:06

大変ありがとうございます。 ご指摘のとおり A==-B の場合は、A=B=0にしたかったです。 わかりやすいコードありがとうございました。 また、よろしくお願いいたします
guest

0

単純に、例えばA列であれば
df.loc[:, 'A']
に置換すれば大丈夫です。

投稿2021/02/24 22:58

Null0lluN

総合スコア59

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問