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

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

ただいまの
回答率

89.13%

【Python】filterによる条件に一致するデータ抽出について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,778

essa

score 52

条件に一致するデータ抽出について質問させてください。

参考にしているサイトは下記です。
https://python.civic-apps.com/map-reduce-filter/

「filter:条件に一致する要素のみ抽出する」

以下のようなコードとなっています(転載させていただきます)

filter(lambda n:n%2==1, items)     #lambda関数がTrueを返す要素(奇数)要素のみ抽出する
[1, 2, 3]
[x for x in items if x%2==1]       #同じ事をリスト内包表記で。(最適な方法)
[1, 3]


条件としている部分をリストにして、
リスト内の値と一つでも一致するなら抽出する。ということをしたいです。

all()関数を使えば実現可能かと思ったのですが、できませんでした。

ご存知のかたがいましたら、教えていただけるとありがたいです。

どうぞよろしくお願いいたします。

=======================
下記追記です。

コードは下記の様な感じです。

# -*- coding: utf-8 -*-
import pandas as pd
import csv
import sys  
code = pd.read_csv("ほげほげ.csv",engine='python',encoding='utf-8') 
codelist = code.values.tolist()
codelist = [ flatten for inner in kcl for flatten in inner ]

with open("ほげほげ書き込み.csv",encoding='utf-8',errors='ignore') as f:
  reader = csv.reader(f)
  header = next(reader)
  rows = [row for row in reader]

with open("hogehogehoge.csv", "w", encoding='utf-8') as f:
  writer = csv.writer(f, lineterminator = "\r\n")
  writer.writerow(header)
  nrows = list(filter(lambda row: row[10] == codelist, rows))
  writer.writerows(nrows)

下から二行目の部分のrow[10]とcodelistが一致しているもののみ、nrowsに代入したいと考えています。

#################

更に追記

#################

ほげほげ.csvが以下です。

品物    A(row[0])    B(row[1])    C(row[2])
あ    111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333111    222    333

ほげほげ書き込み.csvが以下です。

Z
111
222
333
111
222
333
111
222
333
111
222
333

例えばこの場合、AとZを比較します。
そうなると、品物の「あ」「え」「き」「こ」
が抽出できる
というような感じです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • essa

    2018/11/16 17:31

    行数ではなく、列数でした。列数が異なっています。

    キャンセル

  • tiitoi

    2018/11/16 17:47 編集

    data.csv は A, B, C の3列あり、hoge は Z の1列ありますね。そして、data.csv のうち、A列の値がZ列と一致する行を抽出するという認識なのですが、そうではないのでしょうか?回答に記載したCSVと同じであれば、エラーにならないはずです。

    キャンセル

  • essa

    2018/11/16 18:24

    質問が適切でなかったかもしれません。申し訳ありません。もう一度整理して質問したいと思います。

    キャンセル

回答 2

checkベストアンサー

+1

質問の意図を誤解していたらすみません。
条件判定をする関数をリスト化してチェックすればよいのではないでしょうか?

# 条件一覧
cond1 = lambda x: x % 2 == 0  # 2の倍数
cond2 = lambda x: x % 3 == 0  # 3の倍数
cond3 = lambda x: x > 10  # 10より大きい
conds = [cond1, cond2, cond3]

# 入力
lst = list(range(30))

# 出力
filtered = list(filter(lambda x: all([cond(x) for cond in conds]), lst))
print(filtered)  # [12, 18, 24]

データが大量にあるなら、速度的な面で numpy 使ったほうがよいと思います。

import numpy as np

# 入力
lst = np.arange(30)

# 出力
filtered = lst[(lst % 2 == 0) & (lst % 3 == 0) & (lst > 10)]
print(filtered)  # [12, 18, 24]

 追記

追記の例ですと、pandas の機能を使えばよいと思います。

import pandas as pd

data = pd.read_csv('data.csv')
comp = pd.read_csv('hoge.csv')

# data.csv の A 列が hoge.csv の Z 列と一致するもののみ抽出
data[data['A'] == comp['Z']]
品物 A B C
111 222 333
111 222 333
111 222 333
111 222 333

data.csv

品物,A,B,C
あ,111,222,333
い,111,222,333
う,111,222,333
え,111,222,333
お,111,222,333
か,111,222,333
き,111,222,333
く,111,222,333
け,111,222,333
こ,111,222,333
さ,111,222,333
し,111,222,333

hoge.csv

Z
111
222
333
111
222
333
111
222
333
111

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/19 10:27

    新規に質問をさせていただきました。
    https://teratail.com/questions/158979
    確認していただけるとありがたいです。

    キャンセル

0

リスト内の値と一つでも一致するなら抽出する

こういうことですか?

>>> lst = [3, 1, 4]
>>> gen = filter(lambda e: e in lst, range(0, 10, 2))   # 第一引数はlst.__contains__ でも可
>>> list(gen)
[4]

質問編集を受けて

row[10]とcodelistが一致しているもののみ

『row[10]がcodelistに含まれるもののみ』という意味ではなく?
それならこんなふうに書けますが。

filter(lambda row: row[10] in codelist, rows)

さらに追記

要件が発散してきて良く分からないので、考え得る中で一番簡潔な方法を示します。

with open('ほげほげ.csv') as fin1,  \
        open('ほげほげ書き込み.csv') as fin2:

    next(fin1)
    next(fin2)

    for line1, line2 in zip(fin1, fin2):
        item, tag1 = line1.split()[:2]
        tag2 = line2.rstrip()

        if tag1 == tag2:
            print(item)

実行結果

あ
え
き
こ

pandasを使うならばフィルタリングはpandasの機能に頼った方が良いかと。
読み取りでpandasを使ったりcsvモジュールを使ったり、使い分けている意味が良く分かりません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/16 16:31

    質問を追記しました。ご確認いただけると幸いです。

    キャンセル

  • 2018/11/16 16:52

    kclはどこから湧いてきたのですか?

    キャンセル

  • 2018/11/16 17:03

    kclではなく、codelistですね。失礼しました。

    キャンセル

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

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる