87895


DataFrameで「条件に一致した文字("input")から始まる列の値が条件に一致した文字("a")以外であれば抽出」したいです。  
下記のように書くことはできたのですが、もう少し簡潔に書けないでしょうか？

[code]

    import pandas as pd
    
    df = pd.DataFrame(
        [["Yamada", "a", "b", "c"], ["Tanaka", "d", "a", "f"], ["Suzuki", "g", "h", "i"]],
        columns=["name", "input1", "input2", "input3"],
    )
    
    columns = []
    for column in df.columns:
        if column.startswith("input"):
            columns.append(column)
    
    flags = []
    for index, row in df.iterrows():
        flag = False
        for column in columns:
            if row[column] == "a":
                flag = True
        flags.append(flag)
    df["a"] = flags
    df.query("a == False")
    
[/code]


CC BY-SA 4.0
2022-03-18T02:35:22.793
87886
2022-03-18T06:40:13.183
2022-03-18T06:40:13.183
19297
19297
question
python python3 pandas numpy
DataFrameで条件に一致した文字から始まる列の値が条件に一致した文字以外であれば抽出する方法

[code]

    df[(df.filter(regex=r"^input") != "a").all(axis=1)]
    #      name input1 input2 input3
    # 2  Suzuki      g      h      i
    
[/code]

* * *

## 細かい解説

> 条件に一致した文字("input")から始まる行の値が条件に一致した文字("a")以外であれば抽出

まず、縦向きの配列は行ではなく列です。横向きのサブセットが行です。

`input`列を抽出した後、`"a"`と一致するかどうかを確認し、それをもとに行をフィルタリングしましょう。

### 1\. `input`列を抽出

`df.filter()`メソッドは、与えられた文字列に基づいて _列名_ を検索し、一致した列を抽出します。

三種類の方法で検索します。

  * `items`引数 : 完全一致
  * `like`引数 : 与えられた文字列を列名に含む列
  * `regex`引数 : 正規表現

より細かい使い方は下記のサイトを参照してください。  
[pandas.DataFrameから条件を満たす行名・列名の行・列を抽出（選択） |
note.nkmk.me](https://note.nkmk.me/python-pandas-index-columns-select/)

[code]

    df = pd.DataFrame(
        [["Yamada", "a", "b", "c"], ["Tanaka", "d", "a", "f"], ["Suzuki", "g", "h", "i"]],
        columns=["name", "input1", "input2", "input3"],
    )
    
    # `items`による指定は正確だが、対象の列数が多いとキリがない
    df.filter(items=["input1", "input2", "input3"])
    
    # `like`で列名に"input"を含む列を選択する
    # ただしこれは"sub_index"のような列名があった場合は良くない
    df.filter(like="input")
    
    # 列名が"input"で始まる列を選択（最善）
    df.filter(regex=r"^input")
    #   input1 input2 input3
    # 0      a      b      c
    # 1      d      a      f
    # 2      g      h      i
    
[/code]

### 2\. "a"と一致するかどうかの確認

データフレームに比較演算を実行すると、すべての要素に対して比較演算が行われます。  
（[pandasで特定の文字列を含む行を抽出（完全一致、部分一致） | note.nkmk.me](https://note.nkmk.me/python-
pandas-str-contains-match/#_2) も参照してください。）

[code]

    df.filter(regex=r"^input") != "a"
    #    input1  input2  input3
    # 0   False    True    True
    # 1    True   False    True
    # 2    True    True    True
    
[/code]

今回欲しいのは「全ての列が"a"と一致しない」なので、上記のデータフレームの列に対して`all()`を実行します。

[code]

    (df.filter(regex=r"^input") != "a").all(axis=1)
    # 0    False
    # 1    False
    # 2     True
    # dtype: bool
    
[/code]

### 3\. 行フィルタ

ブーリアン配列を`df[]`のカッコ内にわたすと行フィルタできます。詳細は下記サイトを参照してください。  
[pandasで複数条件のAND, OR, NOTから行を抽出（選択） |
note.nkmk.me](https://note.nkmk.me/python-pandas-multiple-conditions/#_1)

ゆえに、2.で得られるものを`df[]`に渡した以下が質問の回答となります。

[code]

    df[(df.filter(regex=r"^input") != "a").all(axis=1)]
    #      name input1 input2 input3
    # 2  Suzuki      g      h      i
    
[/code]


CC BY-SA 4.0
2022-03-18T05:20:08.027
87895
2022-03-18T05:26:25.413
2022-03-18T05:26:25.413
37167
37167
87886
answer