Python Pandasで、2つの値の間のDataFrameの行を選択するにはどうすればよいですか?


99

df列の値が99〜101の行のみを含むようにDataFrameを変更し、closing_price以下のコードでこれを実行しようとしています。

しかし、私はエラーが出ます

ValueError:Seriesの真理値があいまいです。a.empty、a.bool()、a.item()、a.any()またはa.all()を使用します

ループを使用せずにこれを行う方法があるかどうか疑問に思っています。

df = df[(99 <= df['closing_price'] <= 101)]

ここでの問題は、スカラーを配列と比較できないためエラーです。比較の場合、ビットごとの演算子を使用し、演算子の優先順位のためにそれらを括弧で囲む必要があります
EdChum

df.queryそしてpd.eval、このユースケースのために良いフィットのように見えます。pd.eval()関数のファミリー、その機能、および使用例については、pd.eval()を使用したパンダでの動的式評価をご覧ください。
cs95 2018

回答:


103

を使用()してブールベクトルをグループ化し、あいまいさをなくす必要があります。

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]

162

間のシリーズも検討してください。

df = df[df['closing_price'].between(99, 101)]

5
オプションinclusive=Trueはでデフォルトで使用されるbetweenため、次のようにクエリできますdf = df[df['closing_price'].between(99, 101)]
Anton Ermakov

3
これが最良の答えです!よくやった!
PEBKAC 2018

パンダの「間にない」機能はありますか?見つかりません。
dsugasa

2
@dsugasa、チルダ演算子をで使用しbetweenます。
パフェ

1
@dsugasa egdf = df[~df['closing_price'].between(99, 101)]
Jan33

22

より良い代替手段があります -query ()メソッドを使用します

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

更新:コメントに答える:

ここでは構文が好きですが、expresisonと組み合わせようとすると落ちてしまいました。 df.query('(mean + 2 *sd) <= closing_price <=(mean + 2 *sd)')

In [161]: qry = "(closing_price.mean() - 2*closing_price.std())" +\
     ...:       " <= closing_price <= " + \
     ...:       "(closing_price.mean() + 2*closing_price.std())"
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
0             97
1            101
2             97
3             95
4            100
5             99
6            100
7            101
8             99
9             95

ここでは構文が好きですが、expresisonと組み合わせようとすると落ちてしまいました。df.query( '(mean + 2 * sd)<= closing_price <=(mean + 2 * sd)')
domをマッピングします

1
@mappingdom、何ですmeansd?それらの列名はありますか?
MaxU、2017

いいえ、それらは計算された平均と標準偏差をフロートとして保存したものです
マッピングdom

@mappingdom、「保存済み」とはどういう意味ですか?
MaxU、2017

@mappingdom、私は私の投稿を更新しました-それはあなたが求めていたものですか?
MaxU、2017

9

.between()メソッドを使用することもできます

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")

emp[emp["Salary"].between(60000, 61000)]

出力

ここに画像の説明を入力してください


6
newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

または

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')

3

複数の値と複数の入力を扱う場合は、このような適用関数を設定することもできます。この場合、特定の範囲内にあるGPS位置のデータフレームをフィルタリングします。

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]

1

これの代わりに

df = df[(99 <= df['closing_price'] <= 101)]

あなたはこれを使うべきです

df = df[(df['closing_price']>=99 ) & (df['closing_price']<=101)]

クエリを合成するには、NumPyのビット単位の論理演算子|、&、〜、^を使用する必要があります。また、括弧は演算子の優先順位にとって重要です。

詳細については、リンクにアクセスしてください:比較、マスク、ブール論理

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.