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

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

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

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

Q&A

解決済

3回答

15788閲覧

条件にあてはまらないデータを抽出し、別ファイルとして保存したい

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

0クリップ

投稿2018/03/12 05:07

Bのファイルから、Aのファイルのリストと合致しないデータを全て抽出したいのですが、コマンドがわかりません。

例えば、ある市町村の桜開花日のデータがAファイルにあり、Bには調査したい市町村リストがあるとします。
データのない(調査していない)市町村のリストを定期的にチェックしたいと思っています。「isin」の前後にfalseなど入れるのかなと思ったのですが・・・うまくいきませんでした。
エクセルのcountif関数もありますが、pythonだとファイルを開かずにデータ整理ができるので、pythonでできたら良いなと思っています。
リストの列名は、どちらも同じ項目名(この例だと”市町村”)を使用しています。

dfA = pd.read_csv('桜.csv', encoding="cp932")
dfB = pd.read_csv('調査中.csv', encoding="cp932")

list = dfA["市町村"]
df = dfB[dfB["市町村".isin([list])]]
df.to_csv('追加.csv', encoding='cp932')

各リスト(この例だと市町村)をそれぞれ照合し、Aの調査済リストにはないBの市町村をリストアップし、未調査の市町村リストを明確にしたいです。

dfA head(200)
市町村  開花予想日    開花日     
a 2018/03/26   2018/03/26 
c 2018/03/27   2018/03/26  
f 2018/03/28   2018/03/29 
b   2018/03/29   2018/03/28  
p   2018/03/25   2018/03/26  
..............

dfB head(20)
市町村   開花予想日    
c 2018/03/27  
f 2018/03/28       
.......

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

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

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

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

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

guest

回答3

0

ベストアンサー

Python

1lst = dfA["市町村"] 2df = dfB[dfB["市町村"].isin(lst)]

じゃないですかね

list は組み込み関数と同名のため lst と名前を変更させていただきました

投稿2018/03/12 06:00

magichan

総合スコア15898

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

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

magichan

2018/03/12 06:10

おっと、条件は『条件にあてはまらないデータ』なのですね。 であれば、iarikさんが書かれている通り、 df = dfB[~dfB["市町村"].isin(lst)] とする必要がありますね。
退会済みユーザー

退会済みユーザー

2018/03/12 06:32

回答ありがとうございます。出力したいのは、リストに含まれないデータなのです。。。isinだと、リストに含まれているデータが抽出されてしまいます。質問がわかりづらくて申し訳ないです。
magichan

2018/03/12 07:23 編集

要するに dfB["市町村"].isin(lst) にてリストに含まれるデータの Booleanリスト(Series)が得られますので、これの頭に 論理否定('~') を付けて ~dfB["市町村"].isin(lst) とすることで True と False を反転させることができます。 これにより dfB[~dfB["市町村"].isin(lst)] として dfAの"市町村"リストに含まれていないデータが得られます。
退会済みユーザー

退会済みユーザー

2018/03/13 01:53 編集

おかげさまで実行できましたー!! どうもありがとうございます☆ df = dfB[~dfB["市町村"].isin(lst)] の、「~」の部分の表記(記号の大きさ&形)が分かりやすく、 また一言意味を添えて下さったので、ベストアンサーにさせていただきました☆ 実行できたおかげで気分はとっても晴れやかです☆
guest

0

市町村と書きながら23区で申し訳ないですが。
a.csvとb.csvを比較し、b.csvに記載されていない市町村をa.csvから抽出しています。
csvへ出力する際に行番号が不要であればto_csv()の引数にindex=Falseを付与することで非表示にできます。

コード

# -*- coding: utf-8 - import pandas as pd aFile = './a.csv' bFile = './b.csv' outputFile = './c.csv' def main(): aDf = pd.read_csv(aFile) bDf = pd.read_csv(bFile) cDf = aDf[~aDf['市町村'].isin(bDf['市町村'])] print aDf print bDf print "###########################" print cDf cDf.to_csv(outputFile, index=False) if __name__ == '__main__': main()

入力ファイル

  • a.csv
市町村 千代田区 中央区 港区 新宿区 文京区 台東区 墨田区 江東区 品川区 目黒区 大田区 世田谷区 渋谷区 中野区 杉並区 豊島区 北区 荒川区 板橋区 練馬区 足立区 葛飾区 江戸川区
  • b.csv
市町村 新宿区 世田谷区

出力結果

File ./a.csv 市町村 0 千代田区 1 中央区 2 港区 3 新宿区 4 文京区 5 台東区 6 墨田区 7 江東区 8 品川区 9 目黒区 10 大田区 11 世田谷区 12 渋谷区 13 中野区 14 杉並区 15 豊島区 16 北区 17 荒川区 18 板橋区 19 練馬区 20 足立区 21 葛飾区 22 江戸川区 File ./b.csv 市町村 0 新宿区 1 世田谷区 ### result ### 市町村 0 千代田区 1 中央区 2 港区 4 文京区 5 台東区 6 墨田区 7 江東区 8 品川区 9 目黒区 10 大田区 12 渋谷区 13 中野区 14 杉並区 15 豊島区 16 北区 17 荒川区 18 板橋区 19 練馬区 20 足立区 21 葛飾区 22 江戸川区

投稿2018/03/12 06:02

iarik

総合スコア101

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

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

退会済みユーザー

退会済みユーザー

2018/03/12 06:35

回答ありがとうございます。市町村は一例ですので、23区でもかまいません☆出力も理想形で、わかりやすい説明♪と思ったのですが、試したところうまくいきませんでした。 if __name__ == '__main__': main() の部分で、ファイルの名前や項目、ファイル形式によって、 少し変えるべきなのでしょうか。。。
iarik

2018/03/12 07:11 編集

プログラムの書き方なので、main関数を作らずに直列で書いても問題ありません。 # -*- coding: utf-8 - import pandas as pd aFile = './a.csv' bFile = './b.csv' outputFile = './c.csv' aDf = pd.read_csv(aFile) bDf = pd.read_csv(bFile) cDf = aDf[~aDf['市町村'].isin(bDf['市町村'])] print "File "+aFile print aDf print "File "+bFile print bDf print "### result ###" print cDf cDf.to_csv(outputFile, index=False)
iarik

2018/03/12 07:22

後、明示的にエンコードを行う場合は以下のように修正します # -*- coding: utf-8 - import pandas as pd aFile = './a.csv' bFile = './b.csv' outputFile = './c.csv' aDf = pd.read_csv(aFile,encoding='cp932') bDf = pd.read_csv(bFile,encoding='cp932') cDf = aDf[~aDf[u'市町村'].isin(bDf[u'市町村'])] print "File "+aFile print aDf print "File "+bFile print bDf print "### result ###" print cDf cDf.to_csv(outputFile, index=False, encoding='cp932')
退会済みユーザー

退会済みユーザー

2018/03/13 02:06 編集

丁寧なご説明、どうもありがとうございました☆ cDf = aDf[~aDf[u'市町村'].isin(bDf[u'市町村'])] のコマンドのおかげでできました☆ 昨日は「~」の部分が文字化けしたのか、半角よりも小さい「~」となり、 エラーとなったようです。 修正し、無事に実行できました☆
guest

0

出力形式を問わないのならawkとかdiffあたりを組み合わせてワンライナーでできそうです。

市町村が入ってるファイル(A.txt)の形式がこんな感じで

aaa bbb ccc ddd eee fff ggg hhh

データが入っているデータがこんなだったとします。セパレータはスペースかタブ。

aaa 3/30 ddd 4/1 fff 3/31

それぞれのファイルはsortすみ(順番や方法は任意だけど、A.txtもB.txtも同一方法でsortされていること)だとするとこんな感じ。

$ awk '{print $1}' b.txt | diff a.txt - 2,3d1 < bbb < ccc 5d2 < eee 7,8d3 < ggg < hhh

'<'とか、edのコマンドがうるさければgrepとsedで消す。
bがsortされていない場合でも、間にsortをいれればいけるか。

$ awk '{print $1}' b.txt | sort | diff a.txt - | grep '<' | sed -e 's/< //g' bbb ccc eee ggg hhh

投稿2018/03/12 05:48

rogueref

総合スコア727

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

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

退会済みユーザー

退会済みユーザー

2018/03/12 06:31

回答ありがとうございます。diffを使うのですね。こちらのコマンドを少し勉強してから試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問