Ifステートメントを使用して辞書の値を評価するのに問題があります。
データフレームからインポートした次のディクショナリを考えます(重要な場合)。
>>> pnl[company]
29: Active Credit Date Debit Strike Type
0 1 0 2013-01-08 2.3265 21.15 Put
1 0 0 2012-11-26 40 80 Put
2 0 0 2012-11-26 400 80 Put
次の文を評価して、Active
の最後の値の値を確立しようとしました。
if pnl[company].tail(1)['Active']==1:
print 'yay'
ただし、次のエラーメッセージが表示されました。
Traceback (most recent call last):
File "<pyshell#69>", line 1, in <module>
if pnl[company].tail(1)['Active']==1:
File "/usr/lib/python2.7/dist-packages/pandas/core/generic.py", line 676, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Ifステートメントなしで上記のコマンドを使用して必要な値を表示できることを考えると、これは私を驚かせました:
>>> pnl[company].tail(1)['Active']
30: 2 0
Name: Active, dtype: object
値が明らかに0で、インデックスが2であることを考えると、簡単な健全性チェックのために次のことを試してみたところ、予期したとおりに事態が発生していないことがわかりました。
>>> if pnl[company]['Active'][2]==0:
... print 'woo-hoo'
... else:
... print 'doh'
doh
私の質問は:
1)ここで何が起こっているのでしょうか?基本的なレベルで辞書を誤解しているのではないかと思います。
2)この辞書の特定の値を表示すると、左側の数値が1ずつ増加することに気付きました。これは何を表していますか?例えば:
>>> pnl[company].tail(1)['Active']
31: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
32: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
33: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
34: 2 0
Name: Active, dtype: object
助けてくれてありがとう。
生成されるのはPandas Seriesオブジェクトであり、これは、行を次のように変更する必要がある単一の値であっても、試行している方法では評価できません。
_if pnl[company].tail(1)['Active'].any()==1:
print 'yay'
_
2番目の質問に関しては、私のコメントをご覧ください。
[〜#〜] edit [〜#〜]
コメントと出力へのリンクから、any()
を呼び出すとエラーメッセージが修正されますが、データは実際には文字列であるため、比較はまだ失敗します。
_if pnl[company].tail(1)['Active'].any()=='1':
print 'yay'
_
文字列比較を行う、または読み取りまたは生成されたデータを修正する。
または行う:
_pnl['Company']['Active'] = pnl['Company']['Active'].astype(int)
_
比較がより正確になるように、列のdtype
を変換します。
シリーズはNDFrameのサブクラスです。 _NDFrame.__bool__
_メソッド 常にValueErrorを発生させます 。したがって、ブール値のコンテキストでSeriesを評価しようとすると、ValueErrorが発生します-Seriesの値が1つしかなくてもです。
NDFrameがブール値を持たない(つまり、常にValueErrorを発生させる)理由は、NDFrameがTrueであると合理的に期待できる基準が複数あるためです。意味するかもしれない
.all()
を使用)Series.any()
を使用します).empty()
を使用します)どちらかが可能であり、ユーザーごとに異なる期待があるため、開発者は推測することを拒否し、NDFrameのユーザーに使用する基準を明示するよう要求します。
エラーメッセージには、最も可能性の高い選択肢がリストされています。
A.empty、a.bool()、a.item()、a.any()、またはa.all()を使用します
あなたの場合、シリーズには値が1つだけ含まれることがわかっているので、item
を使用できます。
_if pnl[company].tail(1)['Active'].item() == 1:
print 'yay'
_
2番目の質問について:左側の数字は、Pythonインタープリター(PyShell?)によって生成された行番号付けのようです。しかし、それは単なる推測です。
警告:おそらく、
_if pnl[company].tail(1)['Active']==1:
_
seriesの単一の値が1に等しい場合に条件をTrueにしたいことを意味します。コード
_if pnl[company].tail(1)['Active'].any()==1:
print 'yay'
_
seriesのdtypeが数値で、Seriesの値が0以外のanynumberである場合、Trueになります。たとえば、pnl[company].tail(1)['Active']
と等しい
_In [128]: s = pd.Series([2], index=[2])
_
それから
_In [129]: s.any()
Out[129]: True
_
したがって、
_In [130]: s.any()==1
Out[130]: True
_
s.item() == 1
は、意図した意味をより忠実に保持すると思います。
_In [132]: s.item()==1
Out[132]: False
_
_(s == 1).any()
_も機能しますが、any
を使用しても、Seriesに含まれる値は1つだけであることがわかっているため、意図をあまり明確に表現していません。
あなたの質問は、Python辞書、またはネイティブPythonまったく。それは、pandasシリーズ、他の答えはあなたに正しい構文を与えました:
あなたの質問をより広い意味で解釈すると、それは_pandas Series
_がNumPy
にどのようにシューホーンされたのか、そして NumPyは最近まで論理値と演算子のサポートが悪名が悪かった についてです。 pandasはNumPyが提供するもので最高の仕事をします。任意の(Python)演算子でコードを書く代わりにnumpy論理関数を時々手動で呼び出さなければならないのは面倒で不格好で、時には肥大化しますpandasコード。また、パフォーマンスのためにこれを頻繁に行う必要があります(ネイティブPythonとの間でサンクするよりも優れた数値)。しかし、それが代償です。
多くの制限、癖、落とし穴があります(以下の例)-最良のアドバイスは、pandas numpyの制限のため、第一級市民としてのブール値に不信であることです:
パフォーマンスの例: Python〜np.invert()の代わりに使用できます-より読みやすくなりますが、3倍遅くなります
いくつかの落とし穴と制限:以下のコードでは、最近のnumpyがブール値(内部的にintとして表される)とNAを許可するようになったことに注意してください。 value_counts()
はNAを無視します(オプション 'useNA'を持つ Rのテーブル と比較してください)。
。
_import numpy as np
import pandas as pd
s = pd.Series([True, True, False, True, np.NaN])
s2 = pd.Series([True, True, False, True, np.NaN])
dir(s) # look at .all, .any, .bool, .eq, .equals, .invert, .isnull, .value_counts() ...
s.astype(bool) # WRONG: should use the member s.bool ; no parentheses, it's a member, not a function
# 0 True
# 1 True
# 2 False
# 3 True
# 4 True # <--- should be NA!!
#dtype: bool
s.bool
# <bound method Series.bool of
# 0 True
# 1 True
# 2 False
# 3 True
# 4 NaN
# dtype: object>
# Limitation: value_counts() currently excludes NAs
s.value_counts()
# True 3
# False 1
# dtype: int64
help(s.value_counts) # "... Excludes NA values(!)"
# Equality comparison - vector - fails on NAs, again there's no NA-handling option):
s == s2 # or equivalently, s.eq(s2)
# 0 True
# 1 True
# 2 True
# 3 True
# 4 False # BUG/LIMITATION: we should be able to choose NA==NA
# dtype: bool
# ...but the scalar equality comparison says they are equal!!
s.equals(s2)
# True
_