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

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

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

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

Q&A

3回答

930閲覧

padas dataframe 複数条件の入れ子について

MitMc

総合スコア34

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

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

0グッド

1クリップ

投稿2018/07/09 14:43

編集2018/07/10 10:21

dataframeの扱いで、複数条件の抽出が上手くいきません。
開催日のみで絞り込んでから、それを新しいデータフレーム に入れて、その後、レース数で絞り込むという方法以外の方法があれば教えてください。(新しいデータフレームを作らない形でお願いします。)

対象のデータフレーム

開催日 レース
0 2017-01-28 1
0 2017-01-28 2
0 2017-01-28 3
0 2017-01-28 4
0 2017-01-28 5
0 2017-01-28 6
0 2017-01-28 7
0 2017-01-28 8
0 2017-01-28 9
0 2017-01-28 10
0 2017-01-28 11
0 2017-01-28 12
0 2017-01-29 1
0 2017-01-29 2
0 2017-01-29 3
0 2017-01-29 4
0 2017-01-29 5
0 2017-01-29 6
0 2017-01-29 7
0 2017-01-29 8
0 2017-01-29 9
0 2017-01-29 10
0 2017-01-29 11
0 2017-01-29 12
0 2017-01-30 1
0 2017-01-30 2
0 2017-01-30 3
0 2017-01-30 4
0 2017-01-30 5
0 2017-01-30 6
0 2017-01-30 7
0 2017-01-30 8
0 2017-01-30 9
0 2017-01-30 10
0 2017-01-30 11
0 2017-01-30 12

実現したいこと
上記のようなデータフレームにおいて、2017-01-28の5(レース)から2017-01-30の3(レース)までの行を抽出したい。

試したコード

python

1df[[(df["開催日"]>="2017-01-28") &(df["レース"]>=2)]&[(df["開催日"]<="2017-01-30") & (df["レース"]<=5)]]

エラー

TypeError Traceback (most recent call last) <ipython-input-27-bc9d3402f15f> in <module>() ----> 1 new_df[[(day>="2017-01-28") &(race>=2)]&[(day<="2017-01-30") & (race<=5)]] 2 #&new_df[(day<="2017-01-30") & (race<=5)] TypeError: unsupported operand type(s) for &: 'list' and 'list'

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

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

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

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

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

guest

回答3

0

まず最初に。

"開催日"列にて、日時データでの比較演算を行うのであれば、"開催日"列のデータは文字列(Object型)として扱うのではなく、datetime型 で扱いましょう。

その上で条件に会う行の検出は以下のように記述できます。

Python

1import datetime as dt 2res = df[((dt.datetime(2017,1,28) == df["開催日"]) & (df["レース"] >= 2)) | 3 ((dt.datetime(2017,1,29) == df["開催日"]) & (df["レース"] <= 5))]

"レース"列が datetime型 なのであれば単に日付だけの比較で

Python

1res = df[((df["開催日"].dt.day == 28) & (df["レース"] >= 2)) | 2 ((df["開催日"].dt.day == 29) & (df["レース"] <= 5))]

でも良いかもしれません。

以下、動作サンプル

Python

1import datetime as dt 2import pandas as pd 3 4df = pd.DataFrame({ 5 "開催日" : ['2017-01-28'] * 12 + ['2017-01-29'] * 12 + ['2017-01-30'] * 12, 6 "レース" : [1,2,3,4,5,6,7,8,9,10,11,12] * 3 7 }) 8print(df) 9 10df["開催日"] = pd.to_datetime(df["開催日"]) 11 12res = df[((dt.datetime(2017,1,28) == df["開催日"]) & (df["レース"] >= 2)) | 13 ((dt.datetime(2017,1,29) == df["開催日"]) & (df["レース"] <= 5))] 14print(res) 15# レース 開催日 16#1 2 2017-01-28 17#2 3 2017-01-28 18#3 4 2017-01-28 19#4 5 2017-01-28 20#5 6 2017-01-28 21#6 7 2017-01-28 22#7 8 2017-01-28 23#8 9 2017-01-28 24#9 10 2017-01-28 25#10 11 2017-01-28 26#11 12 2017-01-28 27#12 1 2017-01-29 28#13 2 2017-01-29 29#14 3 2017-01-29 30#15 4 2017-01-29 31#16 5 2017-01-29

投稿2018/07/09 23:34

magichan

総合スコア15898

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

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

MitMc

2018/07/10 10:29

ご回答ありがとうございます。 申し訳ないのですが、質問を変更させていただきました。 1月28日と1月29日であれば、いただいたコードの通りなのですが、この期間が1月28日〜30日となった場合(実際はもっと長期の期間を想定しているのですが、teratailへの質問上、短い期間としてます)、 日が連続していないので、==で指定してしまうと29日が抜けてしまいます。 しかし>=、<=で指定すると、求めている以上の日付が選択されてしまいます。この場合、どうしたら良いでしょうか?
magichan

2018/07/10 11:55

単純に日付("開催日"列)だけの絞込み、例えば、 『1/10 から 1/29 までの全レース』などの場合 df[(dt.datetime(2017,1,10) <= df["開催日"]) & (dt.datetime(2017,1,29) >= df["開催日"])] のように不等号を使っても全く問題ないと思います。 問題は"レース"列を含んで『1/10の4レース から 1/29の5レースまで』などの場合ですね・・ その場合は条件文を並べて df[((dt.datetime(2017,1,10) == df["開催日"]) & (df["レース"] >= 4)) | ((dt.datetime(2017,1,11) <= df["開催日"]) & (dt.datetime(2017,1,28) >= df["開催日"])) | ((dt.datetime(2017,1,29) == df["開催日"]) & (df["レース"] <= 5))] のように書くとよいのではないでしょうか
KojiDoi

2018/07/10 12:31

MitMcさん まさにそういう状況を考慮して私は「日付とレース番号を纏めたもの」をまず作って大小比較を試みるコードを書きました。 中日を考慮して複雑なand式を立てるよりシンプルだと思います。 試してみて頂きたい。
MitMc

2018/07/10 22:23

magichan様 再度、教えていただき、ありがとうございます。 参考にいたします。
MitMc

2018/07/10 22:28

KojiDoi様 頂いたコードを試したのですが、dataframeが空になり、上手くいきませんでした。 前提としてお話しすべきだったのですが、開催日は文字列ではなく、datetimeになっております。そのせいで上手くいかなかったのでしょうか? 再度、string型に直してみてから試そうと思うのですが、なかなか上手くいかず.... df["開催日"].string()では駄目でしょうか。
guest

0

「実現したいこと」に書いてある条件はどう見ても矛盾しているので無視して、2017-01-28第2レースから2017-01-29第5レースまでを選択するコードを書いてみました。

python

1df1[ 2 (df1.apply(lambda x: "{} {:02}".format(x["開催日"], x["レース"]), axis=1)>="2017-01-28 02") & 3 (df1.apply(lambda x: "{} {:02}".format(x["開催日"], x["レース"]), axis=1)<="2017-01-29 05") 4]

追記: datetime型をサポートしうまくいったコード全体を示します。

#!/usr/bin/env python3 import pandas as pd import io df1 = pd.read_table(io.StringIO(""" 開催日 レース 0 2017-01-28 1 0 2017-01-28 2 0 2017-01-28 3 0 2017-01-28 4 0 2017-01-28 5 0 2017-01-28 6 0 2017-01-28 7 0 2017-01-28 8 0 2017-01-28 9 0 2017-01-28 10 0 2017-01-28 11 0 2017-01-28 12 0 2017-01-29 1 0 2017-01-29 2 0 2017-01-29 3 0 2017-01-29 4 0 2017-01-29 5 0 2017-01-29 6 0 2017-01-29 7 0 2017-01-29 8 0 2017-01-29 9 0 2017-01-29 10 0 2017-01-29 11 0 2017-01-29 12 0 2017-01-30 1 0 2017-01-30 2 0 2017-01-30 3 0 2017-01-30 4 0 2017-01-30 5 0 2017-01-30 6 0 2017-01-30 7 0 2017-01-30 8 0 2017-01-30 9 0 2017-01-30 10 0 2017-01-30 11 0 2017-01-30 12 """), delim_whitespace=True ) df1["開催日"] = pd.to_datetime(df1["開催日"]) df2 = df1[ (df1.apply(lambda x: "{} {:02}".format(x["開催日"], x["レース"]), axis=1)>="2017-01-28 00:00:00 02") & (df1.apply(lambda x: "{} {:02}".format(x["開催日"], x["レース"]), axis=1)<="2017-01-29 00:00:00 05") ] print(df2)

投稿2018/07/09 18:50

編集2018/07/14 03:50
KojiDoi

総合スコア13671

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

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

0

start_df = new_df[(day=="2017-01-28") &(race>=2)]
end_df = new_df[(day=="2017-01-30") &(race<=5)]
middle_df = new_df[(day>"2017-01-28") &(day<"2017-01-30") ]

pd.concat([start_df, middle_df,end_df ])

投稿2018/07/10 10:57

MitMc

総合スコア34

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問