🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

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

Q&A

解決済

1回答

773閲覧

pythonで複数のテキストから抽出したものも%(頻度)の求め方について

yusuke1818

総合スコア10

Python

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

0グッド

0クリップ

投稿2020/12/18 05:57

編集2020/12/18 13:55

ファイル1
ATOM 2 CA PRO A 2 29.341 -18.244 23.236 1.00112.52 C
ATOM 9 CA LYS A 3 28.103 -17.550 19.692 1.00 91.13 C
ATOM 18 CA PRO A 4 29.134 -14.592 19.578 1.00 63.64 C
ATOM 51 CA GLY A 5 24.012 -5.835 11.284 1.00 25.93 C
ATOM 1605 CA LYS B 1 8.357 5.403 38.590 1.00 58.36 C
ATOM 1614 CA PRO B 2 6.423 2.744 36.650 1.00 49.68 C
ATOM 1621 CA PHE B 3 7.816 1.954 33.187 1.00 42.38 C
ATOM 1623 CA PHE B 4 7.816 1.954 33.187 1.00 42.38 C
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ファイル2
ATOM 51 CA GLY A 1 24.012 -5.835 11.284 1.00 25.93 C
ATOM 55 CA ILE A 2 23.574 -2.078 10.974 1.00 25.44 C
ATOM 63 CA ALA A 3 22.508 -0.631 7.650 1.00 33.94 C
ATOM 68 CA GLY A 4 20.982 2.603 6.424 1.00 29.02 C
ATOM 69 CA GLY A 5 20.982 2.603 6.424 1.00 29.02 C
ATOM 1614 CA PRO B 2 6.423 2.744 36.650 1.00 49.68 C
ATOM 1621 CA PHE B 3 7.816 1.954 33.187 1.00 42.38 C
ATOM 1623 CA PHE B 4 7.816 1.954 33.187 1.00 42.38 C
ATOM 1623 CA PHE B 5 7.816 1.954 33.187 1.00 42.38 C

上記の2つのテキストファイルがある。
そのテキストファイルと同じフォルダに下記のコードが存在する。
内容は、これら同じフォルダ内のファイルを一括で読み込み、ATOM、CA、Aという文字を含む行とATOM、CA、Bという文字を含む行をぞれぞれ分けて抽出し、
左から6個目の要素(今回ではファイル1でいう、Aの2,3,4,5, Bの1,2,3,4)の数字がAとBでぞれぞれいくつからいくつがつながっているか(今回ではファイル1でいう、Aは2-5、Bは1-4)を調べるプログラムを作った。
下記のコードを実行して、
結果は
-------- pdb1ufq.ent(今回のファイル1) --------
A側のCA
[2, 5]

B側のCA
[1, 4]
-------- pdb3asy.ent(今回のファイル2) --------
A側のCA
[1, 5]

B側のCA
[2, 5]
となる。
そしてここからやりたいのはこのそれぞれの結果のA側だけ、B側だけ、AもBも含めた全体の範囲の頻度をそれぞれ3種類求めたい。
今回でいう
A側だけ↓
1  50%
2-5 100%
B側だけ↓
1  50%
2-4 100%
5  50%
AもBも含めた全体の範囲↓
1  50%
2-4 100%
5  75%
という感じにしたいです。
下記コードにどのようにしたらこのようなものを求められるでしょうか?お願いします。
もしかしたらデータを抽出する段階でpandasのDateFrameで作ったほうが良かったかもしれません。
そうすればvalue_countで数えられたかもしれません。どちらの方法でも構わないので分かる方お願いいたします。

import tkinter from selenium import webdriver from time import sleep import requests from bs4 import BeautifulSoup import more_itertools as mit import glob # テキストファイルのみを取得 list1=glob.glob("*.ent") print(list1) for name in list1: def consecutive_groups(iterable): """Yield range of consecutive numbers.""" for group in mit.consecutive_groups(iterable): group = list(group) if len(group) == 1: yield group[0] else: yield group[0], group[-1] path = name print("--------",name,"--------") serial_numbers_A = [] serial_numbers_B = [] with open(path) as f: lines = f.readlines() lines_strip = [line.strip() for line in lines] #A側のCAの抽出----------------------------- for A_and in lines: A_and=A_and.split() if A_and[0] == 'ATOM' and A_and[2] == 'CA' and A_and[4] == 'A': serial_numbers_A.append(int(A_and[5])) print("A側のCA") for Agroup in consecutive_groups(serial_numbers_A): print(list(Agroup)) #B側のCAの抽出----------------------------- for B_and in lines: B_and=B_and.split() if B_and[0] == 'ATOM' and B_and[2] == 'CA' and B_and[4] == 'B': serial_numbers_B.append(int(B_and[5])) print(" ") print("B側のCA") for Bgroup in consecutive_groups(serial_numbers_B): print(list(Bgroup))

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

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

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

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

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

jbpb0

2020/12/18 06:28

前提条件によって変わりますよね ・数字は連番の場合しか無いのか? 途中が抜ける場合もあるのか? 必ず増えるのか? 同じ数字が続くことは無いのか? ・数字の範囲は決まってるのか? 負やゼロもあるのか? 最大値は分かるのか? とか
yusuke1818

2020/12/18 06:34 編集

すいませんありがとうございます。 必ず連番ではなく途中が抜けている可能性はあります。AごとBごとではそれぞれ増えていくことしかありません。同じ数が続くことはありません。 数字は1以上で負やゼロもありません。最大値はおそらく300行かないくらいだと思いますがファイルによるのでわかりません。
guest

回答1

0

ベストアンサー

python

1from itertools import groupby # <--追加。 2 3def cut(source): 4 # source内の要素が抜けている場合に対応。さらに連続数のグループに分割する。 5 fix_source = [tuple(map(lambda s: s[1], g)) for item in source for _, g in groupby( 6 enumerate(item), key=lambda x:x[0]-x[1])] # <--追加 7 8 # 先頭数の昇順で並び替える。 9 sr = sorted(fix_source, key=lambda x: x[0]) # <--修正 10 11 # カッティング対象 12 g = set() 13 # スライスインデックス 14 k = set() 15 16 # カッティング対象を格納 17 gg = [] 18 # スライスインデックスを格納 19 kk = [] 20 for i in sr: 21 if g and max(g) < min(i): 22 gg.append(tuple(g)) 23 kk.append(k) 24 g = set(i) 25 k = set((min(i), max(i)+1)) 26 g |= set(i) 27 k |= set((min(i), max(i)+1)) 28 gg.append(tuple(g)) 29 kk.append(k) 30 31 kk = [sorted(map(lambda x:x-min(s), s)) for s in kk] 32 # スライスインデックスに従って切る 33 return [g[k[j]:k[j+1]] 34 for g, k in zip(gg, kk) 35 for j in range(len(k)-1) 36 ] 37 38 39def pred(source): #<----修正 40 piece = cut(source) #<----修正 41 ans = {} 42 for b in piece: 43 ans.setdefault(b, 0) 44 for aa in source: 45 if set(b) <= set(aa): 46 ans[b] += 1/len(source) 47 return ans

python

1def print_fmt(answers): 2 for k, v in answers.items(): 3 print("{0:<5} {1:>5.1f}%".format(k[0] if len(k) == 4 1 else str(k[0])+"-"+str(k[-1]), v*100)) 5 print() 6 7 8A_CA= [[1, 2, 4, 5], [3, 4, 5, 6, 7], [3, 4, 5, 8]] 9print_fmt(pred(A_CA)) #<----まとめて呼び出せるようにした

出力結果

1-2 33.3% 3 66.7% 4-5 100.0% 6-7 33.3% 8 33.3%

投稿2020/12/18 16:33

編集2020/12/22 04:34
sfdust

総合スコア1137

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

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

yusuke1818

2020/12/19 00:31

なるほどやり方理解しました!ありがとうございます。 これとつなげるように後は頑張ります! 本当にありがとうございました!
yusuke1818

2020/12/19 01:06 編集

A_CA = [(2, 3, 4, 5), (1, 2, 3, 4, 5)] B_CA = [(1, 2, 3, 4), (2, 3, 4, 5)] って多次元リストですか?それとも別物ですか? A_CA = [[2, 3, 4, 5], [1, 2, 3, 4, 5]] B_CA = [[1, 2, 3, 4], [2, 3, 4, 5]]ではだめですか?
sfdust

2020/12/19 02:36 編集

どちらでも(A_CA = [(2, 3, 4, 5), (1, 2, 3, 4, 5)] でも A_CA = [[2, 3, 4, 5], [1, 2, 3, 4, 5]]でも)大丈夫です。
yusuke1818

2020/12/20 01:35

これは連続した数字ではなく間が抜けていたりするとそれを識別しますか? A_CA = [[2, 3, 4, 5], [1, 2, 3, 4, 5]]のような形でやってみたのですが識別が出来ませんでした。
sfdust

2020/12/20 02:38 編集

・「間が抜けていたりする」、「識別する」、というのはそれぞれどういう意味でしょうか。 ・「A_CA = [[2, 3, 4, 5], [1, 2, 3, 4, 5]]のような形」のどこが「間が抜けている」のでしょうか。 与えるデータと、それを与えた場合に期待する結果を、プログラムできる形に具体的に示してください。 「抜けている」とは、たとえば [[1,2,4,5], [3,4,5,6,7]]というデータを与えたとき、という意味でしょうか。(1番目の要素で「3」が抜けている) ならば、このデータを与えた場合のあるべき結果(最終的にどのような範囲を抽出し、各何%であるべきなのか)を示してください。
yusuke1818

2020/12/21 02:11

A_CA=[[19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230], [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230]] ---A_CA--- 19-230 50% となりました。 リストの中の2つ目は47の次が52であるのに、そこを識別していませんでした。 どうしてそうなってしまったのでしょうかすいません。
sfdust

2020/12/21 06:09 編集

回答したプログラムでは、リストの中で間が抜けている場合は、連続しているものとして扱っているためそのようになります。 間が空いているデータが与えられる可能性を想定していなかったといえばそれまでなのですが(質問文記載の例は、すべてリストの中身は連続している数になっています) リストの中に間が抜けているデータが与えられた場合、どのような答えとなるべきなのでしょうか? こちらとしてはエスパーではないので、それを教えていただけないとプログラムに反映できません。 繰り返しになりますが、たとえば、[[1,2,4,5], [3,4,5,6,7]]というデータを与えたとき、どのような答えを表示すべきなのでしょうか? (こちらとして考えられるパターンはいくつかありますが、決めつけることはできないので)
yusuke1818

2020/12/22 01:42 編集

大変申し訳ありませんでした。 [[1,2,4,5], [3,4,5,6,7]]でしたら、 1-3 50% 4-5 100% 6-7 50% です。 リストの中に2つリストがあって、片方にしかないものは、50%、どっちにもあるものは100%です。 例えば[[1,2,4,5], [3,4,5,6,7],[3,4,5,8]]だとしたら、3つのリストの中で1つのリストにしかないものは33.3%、2つあったら66.6%、3つあったら100%なので 1-2 33.3% 3 66.6% 4-5 100% 6-8 33.3% となります。 リストの中に4つや5つでも同様で、いくつあっても出来るようにしたいのです。 説明不足で大変申し訳ございません。
sfdust

2020/12/22 02:34 編集

その2つ(2020/12/22 10:41 時点)と、これまでの分け方の規則の共通性が分かりません。 [[1,2,4,5], [3,4,5,6,7]]の場合 なぜ(1,2), (3) ,(4,5), (6,7)の4グループに分けるのではなく (1,2,3),(4,5),(6,7)という分け方になるのでしょうか。 同様に、[[1,2,4,5], [3,4,5,6,7],[3,4,5,8]]の場合 なぜ (1.2),3,(4,5),(6,7),8 の5グループではなく (1,2),3,(4,5),(6,7,8)という分け方になるのでしょうか。
yusuke1818

2020/12/22 02:36

すいません、%が同じものをまとめて記述してしまっただけです。 [[1,2,4,5], [3,4,5,6,7]]の場合 (1,2), (3) ,(4,5), (6,7)の4グループ [[1,2,4,5], [3,4,5,6,7],[3,4,5,8]]の場合 (1.2),3,(4,5),(6,7),8 の5グループで問題ありません。
sfdust

2020/12/22 04:33

御希望の動作になるようにソースを修正しました。 (同じ頻度をまとめる機能については対応しません)
yusuke1818

2020/12/22 04:45

完全にできました!!!!! 分かりずらい私の説明の中、たくさんの要望に応えていただき大変ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問