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

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

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

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

Python

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

Q&A

解決済

4回答

1344閲覧

python or と | の違いを教えてください。

Y.Arai

総合スコア42

JupyterLab

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

Python

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

0グッド

2クリップ

投稿2022/01/01 13:49

下記のコードは、エラーが起きません。

# status 1支払い済み 2お渡し済み 絞る order_all=order_data.loc[(order_data['status']==1) | (order_data['status']==2)]

しかし、orにするとエラーになります。

# status 1支払い済み 2お渡し済み 絞る order_all=order_data.loc[(order_data['status']==1) or (order_data['status']==2)]

エラーは、

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) /var/folders/ps/xxgp4_3j0sq5_9pz2s204c080000gn/T/ipykernel_1311/996920767.py in <module> 1 # status 1支払い済み 2お渡し済み 絞る ----> 2 order_all=order_data.loc[(order_data['status']==1) or (order_data['status']==2)] ~/opt/anaconda3/lib/python3.9/site-packages/pandas/core/generic.py in __nonzero__(self) 1535 @final 1536 def __nonzero__(self): -> 1537 raise ValueError( 1538 f"The truth value of a {type(self).__name__} is ambiguous. " 1539 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

です。
and と | の違いは、優先順位の違いでだけと思っていたので、カッコで括っているたので、同じ挙動になると
思っていました。

ご教授いただけると助かります。
よろしくお願いします。

*jupyter labで実行しています。

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

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

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

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

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

guest

回答4

0

ベストアンサー

動作からの私の推測を含めて回答します。

まず
(order_data['status']==1) と (order_data['status']==2)は

type(order_data['status']==1)を実行すればわかるようにPandasのSeriesです。

Series同士の | の演算は、Seriesでは各要素同士の | の演算の結果をSeriesとして返すようにで定義されています。

対して、Series同士の or の演算では、a or b とした場合、まず aを boolに変換してチェックするようで、その際にSeriesで定義された
__bool__が呼び出されるようで、そこでエラーとなるようです。(__bool__=__nonzero__と定義されているので、ログに出るのは__nonzero__の方のようですが)

実際に、エラーが出ていた__nonzero__の関数をreturn Trueを返すように修正すると
(order_data['status']==1) or (order_data['status']==2)
は処理が可能になり(order_data['status']==1)がTrueと判定される為、(order_data['status']==1)が取得されます。

結局、繰り返しになりますが
| は、or は別物で、| に関しては、pandasのSeriesで実装されており要素同士の | の結果をSeriesとして返却してくれる
or は、a or b とした場合まずaを一旦boolに変換する処理が実行され、そのboolに変換する処理がpandasのSeriesで実装されているがエラーを返すだけの実装になっている。

という事のようです。

私はこれで何となくなるほど。と思ったのですが
間違ってる点とかあれば指摘して頂けるとありがたいです。

投稿2022/01/01 21:09

編集2022/01/01 21:31
xail2222

総合スコア1508

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

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

Y.Arai

2022/01/04 05:45 編集

わかりやすい回答ありがとうございます。 納得です。
guest

0

and と | の違いは、優先順位の違いでだけと思っていたので、

orとのタイプミスだと思いますが、
or|は全然違います。|は二項演算子で、その扱うデータのクラスで__or__というメソッド名で定義された処理をします。pandasをお使いだと思いますが、pandasのクラスで__or__は定義されています。データフレームの要素を個別に|して、結果をデータフレームとして返すように定義されているようです。

orは制御構造で、左項を評価して真偽値に変換してTrueなら(返還前の)左項を結果とし(右項は評価しない)、Falseなら右項を評価してそれを結果とします。

そのエラーは、データフレームが単一の真偽値に変換できないというエラーです。「複数の値からどうやって単一の真偽値に変換するか」を明示する必要があります。変換したとしてもそれはデータフレームじゃないので、|の結果と同じにはなりません。

左項と右項が両方とも(副作用の無い)真偽値の時はor|は同じですかね。

投稿2022/01/01 15:44

編集2022/01/01 16:10
otn

総合スコア85901

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

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

Y.Arai

2022/01/04 05:44

納得です。 ありがとうございました。
guest

0

  • python or と | の違いを教えてください。

演算子or公式ドキュメント Python 言語リファレンス 6.11. ブール演算 (boolean operation)に書かれているように、式 x and y は、まず x を評価します; x が偽なら x の値を返します; それ以外の場合には、 y の値を評価し、その結果を返します。という演算子です。

演算子公式ドキュメント Python 言語リファレンス 6.9. ビット単位演算の二項演算 (binary bitwise operation)に、| 演算子は、引数同士のビット単位の (包含的) OR を与えます。引数は整数でなければなりません。と書かれています。しかし、公式ドキュメント Python 言語リファレンス 3.3.8. 数値型をエミュレートするに書かれているように特殊メソッド__or__を使うことでクラスごとに定義することが可能です。

整数を対象とする場合、以下の違いがあります。

python

1>>> print(2 or 1) 22 3>>> print(2 | 1) 43

Python処理系は、演算子orに対して、JUMP_IF_TRUE_OR_POPというバイトコードを生成します。
一方、演算子``````に対して、BINARY_ORというバイトコードを生成します。
その説明は、公式ドキュメント Python 標準ライブラリ dis --- Python バイトコードの逆アセンブラをお読みください。

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
といエラーが出るのは、pandas.Seriesの場合には、JUMP_IF_TRUE_OR_POPでの__bool__をそうなるように上書きしているためです。

python

1>>> import pandas as pd 2>>> s = pd.Series([True, False]) 3>>> print(s) 40 True 51 False 6dtype: bool 7>>> bool(s) 8Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 File "C:\Users\shinp\anaconda3\envs\sandbox\lib\site-packages\pandas\core\generic.py", line 1537, in __nonzero__ 11 raise ValueError( 12ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

投稿2022/01/01 15:53

編集2022/01/01 16:03
ppaul

総合スコア24670

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

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

Y.Arai

2022/01/04 05:43

詳細なご回答ありがとうございます。 参考になります。 ありがとうございます。
guest

0

orと|、まったく違います。

Python

1>>> 2 | 1 23 3>>> 2 or 1 42

片や論理和、片やビット論理和、意味合いは確かに似ています。
実際、オペランド(演算対象)を論理型に限る分には同じように見えるでしょう。


pandasにおいては | をオーバーロードして別の計算をさせているようですから、
なおさら or とは意味が乖離していきます。

投稿2022/01/01 15:35

LouiS0616

総合スコア35668

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

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

Y.Arai

2022/01/04 05:45

なるほど 他のご回答者もおっしゃられた通り、pandasはさらに意味が違うようですね。 理解しました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問