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

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

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

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

Python

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

pandas

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

Q&A

解決済

2回答

2317閲覧

pandasでの行の抽出について

fu_3823

総合スコア81

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

Python

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

pandas

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

0グッド

1クリップ

投稿2020/12/15 05:37

編集2020/12/15 06:08

以下のようなサンプル、dfについて考えています。

________id________name_______diff_________num
0 000 aaa 3.0 1
1 111 bbb 123.0 2
2 222 bbb 0.0 2
3 333 bbb 4.0 2
4 444 ccc 333.0 3
5 555 ccc 3.0 3
6 666 ddd 1234.0 4
7 777 eee 4567.0 5
8 888 eee 5.0 6
9 999 eee 2.0 6

この中からnameが同じでdiffが小さいにもかかわらず、numがひとつ前の行から変化してしまっている要素をエラーと考えます。この時、間違った更新が行われた二行のデータセットを、1万行の中から全てデータフレームとして取り出したいです。
サンプルの場合は、7行と8行が該当します。
抽出条件にdf.loc[i, 'name'] == df.loc[i+1, 'name'] and df.loc[i+1, 'diff'] < 100
などを考えましたが、データフレーとして取り出せません。うまい方法はありませんでしょうか。
言語は pythonです。

補足
diffですが、ルールでは値が100以上であれば、ひとつ上の要素とは違うnameとnumを持ちます。
逆に100未満であれば、同じnameを持ち、numも同じ値になります。
上記サンプルのインデックスが7と8について、8のnumは5であるはずが、6に更新されています。その結果インデックス9のnumも6になってしまっているというケースです。

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

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

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

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

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

plasticgrammer

2020/12/15 05:44

理解できない点があるので補足をお願いします。 「diffが小さいにもかかわらず」とはどういう意味でしょうか。 「nameが同じでnumが変わった」という条件だけでなく、 このdiffが抽出条件にどう影響するのかがイメージできません。
fu_3823

2020/12/15 06:09

すみません。補足いたしました。
guest

回答2

0

ベストアンサー

以下のデータフレームを例にします。

python

1In [11]: df 2Out[11]: 3 id name diff num 40 0 aaa 3.0 1 51 111 bbb 123.0 2 62 222 bbb 0.0 2 73 333 bbb 4.0 2 84 444 ccc 333.0 3 95 555 ccc 3.0 3 106 666 ddd 1234.0 4 117 777 eee 4567.0 5 128 888 eee 5.0 6 139 999 eee 2.0 6

pd.Series.shift()を用いると、ある列を一行分ずらすことができます。pandasを用いて「一つ上/下の行と比較」のような作業を行う場合は基本的にこれを用います。
なお、shift()の引数に整数を与えると、その値分ずらすことができます。
pandas.Series.shift — pandas documentation
pandasでデータを行・列(縦・横)方向にずらすshift | note.nkmk.me

python

1In [12]: df[['name', 'num']].shift() 2Out[12]: 3 name num 40 NaN NaN 51 aaa 1.0 62 bbb 2.0 73 bbb 2.0 84 bbb 2.0 95 ccc 3.0 106 ccc 3.0 117 ddd 4.0 128 eee 5.0 139 eee 6.0

したがって、条件式を用いたデータ抽出を行って、「nameがひとつ上の行と同じ」かつ「numがひとつ上の行と同じ」かつ「diffが100未満」の行を以下のコードで得ることができます。

python

1In [13]: cond = ((df['name'] == df['name'].shift()) 2 ...: & (df['num'] != df['num'].shift()) 3 ...: & (df['diff'] < 100)) 4 ...: cond 5Out[13]: 60 False 71 False 82 False 93 False 104 False 115 False 126 False 137 False 148 True 159 False 16dtype: bool 17 18In [14]: df[cond] 19Out[14]: 20 id name diff num 218 888 eee 5.0 6

これで誤っている行は抽出できました。今回はその一つ上の行もほしいということなので、以下の操作を行います。

条件式から得たT/F配列のcond.shift(-1)を適用して一つ上にずらし、元のcondとany(|)を取ることで、Trueの行のひとつ上の行をFalseからTrueにすることができます。

python

1In [15]: cond | cond.shift(-1, fill_value=False) 2Out[15]: 30 False 41 False 52 False 63 False 74 False 85 False 96 False 107 True 118 True 129 False 13dtype: bool 14 15In [16]: df[cond | cond.shift(-1, fill_value=False)] 16Out[16]: 17 id name diff num 187 777 eee 4567.0 5 198 888 eee 5.0 6

投稿2020/12/15 08:57

kirara0048

総合スコア1399

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

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

fu_3823

2020/12/17 06:27

丁寧なコードありがとうございました。 大変参考になりました。
guest

0

python

1result = df[(df['name'] == df['name'].shift()) & (abs(df['diff'] - df['diff'].shift()) < 100) | (abs(df['diff'] - df['diff'].shift(-1)) < 100) & ~(df['num'] == df['num'].shift()) & ~(df['num'] == df['num'].shift(-1))]

投稿2020/12/15 07:47

meg_

総合スコア10577

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問