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

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

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

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

Q&A

解決済

2回答

622閲覧

python ファイル 読み込み 並べ替え

makaron

総合スコア11

Python

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

0グッド

0クリップ

投稿2018/08/01 09:29

編集2018/08/01 10:00

前提・実現したいこと

現在pythonを用いてデータの分析を行っています。今回、自分では難しくてコードを書くのにつまってしまう事態が発生したので質問させていただきます(調べたりしたのですがどうにも無理でした、、)
あるファイル(大量のデータ)を読み込み、いくつかの項目に着目し、ランキング付けして別のファイルに書き込むということを行いたいです。

発生している問題・エラーメッセージ

いくつもの項目を同時にみるというコードの書き方ができずに、1つの項目のみにしか着目できませんでした。ここからの改善点をおしえていただきたいです。

(読み込むファイル)
1 2 3 4 5
123/t 12345/t 4786/t 1564/t 7045
145/t 12349/t 4786/t 1567/t 7896
149/t 12351/t 4790/t 1546/t 8967
186/t 12356/t 4786/t 1589/t 8564
123/t 12378/t 4790/t 1544/t 8496

このようにタブ区切りで5つの項目が並べられているファイルがあります(データ数多い)
これを順番にみていきます。
1項目目をIDとします。
まず、1列目の3項目目に着目し、他の列の3項目目と比較し、同じものがあればそれらの4項目目を比較します。1列目の4項目目を基準に比較してそれより他が大きければその列のIDを+1,小さいもしくは同じならばそのままにします。
これをすべての列に対して行いたいです。
最後は数値が多い順にランク付けします。

つまり書き出すコードとしてはこの場合以下のようにしたいです。
1 123 3
2 145 1
(0回は表示しない)
これは別のファイルに書きたいです。

該当のソースコード

python

1ファイルよみこみ 2 3id_count={} 4lineN = 0 5for line in f(よみこみファイル) 6 inputs = line.split("\t") 7 if len(inputs) != 5 8 continue 9 10 if (id_count.has-key(inputs[1])): 11 id_count[inputs[1]] += 1 12 else: 13 id_count[inputs[1]] = 1 14

このようなソースコードまで書けましたが、これは
私がやりたい項目比較を満たせていません。
パソコンからなぜか質問ができず、スマホから打っているため見ずらかったら申し訳ありません。

質問が分かりにくく申し訳ありません。
ご回答していただければ幸いです。よろしくお願いします。

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

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

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

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

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

LouiS0616

2018/08/01 09:45

ご提示のソースコードは、エラーが多発してまともに実行できないと思うのですが... 打ち間違いが多くあるように思います。ご確認ください。
makaron

2018/08/01 09:56

こんにちは!ご指摘ありがとうございます。はい、パソコンのコードをスマホから入力しており、うまくコードがかけていません。なぜ、パソコンから質問の投稿ができないのか解決方法が分からずいままずそちらを解決しようとしています。スマホからもう一度修正してコード掲載いたしますが、また間違っていたら申し訳ありません。ご確認お願いします。
makaron

2018/08/01 10:01

修正いたしました。よろしくお願いいたします。
LouiS0616

2018/08/01 10:36

『データ数多い』とありますが、具体的には何行くらいあるのでしょうか。
makaron

2018/08/01 10:39

ご質問ありがとうございます。はい、1万行は越えます。
hayataka2049

2018/08/01 12:33

1列目じゃなくて1行目では?(ふつう横方向が行、縦方向が列です) ID123はID145,186と比較されてともに比較対象より4項目目が小さいので、スコアは2になるのでは?
hayataka2049

2018/08/01 12:34

あっ、IDの重複があるんですね。4項目目が4790のときの比較で+1されるということでしょうか(見落としてた)
hayataka2049

2018/08/01 12:37

というか、これ本当に「データの分析」ですか?(競プロとかではなく)
makaron

2018/08/01 13:06

ご質問ありがとうございます。はい、そういうことです。本当にデータの分析です!自分の学校の勉強です。アドバイスおねがいします。ごめんなさい、競プロの言葉の意味がわからないのですが、違うと思います。
guest

回答2

0

単純に実装すると毎回全要素を比較しなければならないため、効率が非常に悪いです。
特にデータのサイズが1万行を超えるのですから、この悪効率は無視できません。

データを全て読み取って操作すると効率が良くなります。
しかし、効率の代償として今度はメモリが圧迫されます。これも無視できません。


ここで生まれる折衷案は、前以てファイルを分割することです。
扱いやすく分割するには、3項目目をカギにして分類すれば良いことに気付きます。

10から100ほどのファイルに分割できるような分類方法を考えてください。


データが全部読み取れるなら、こんな感じで書けます。

Python

1from collections import Counter 2import pandas as pd 3 4 5with open('src.csv') as fin: 6 df = pd.read_csv( 7 fin, header=None, delim_whitespace=True 8 ) 9 10id_count = Counter() 11for _, group in df.groupby(2): 12 group = group.sort_values(by=3, ascending=False) 13 14 for i, (_, series) in enumerate(group.iterrows()): 15 idd, *_ = series 16 id_count[idd] += i 17 18it = enumerate(id_count.most_common(), start=1) 19for i, (key, value) in it: 20 if value == 0: 21 break 22 23 print(i, key, value)

pandasは書きなれていないので、多少ダサいコードだとは思います。

投稿2018/08/01 12:19

編集2018/08/01 13:30
LouiS0616

総合スコア35658

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

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

makaron

2018/08/01 15:42

細かい回答ありがとうございます。 if文の中で、if文をまわしたり、for文の中でfor文を回すというところまでは、自分でもやってみたのですが、うまくいかず、このように書けばいいのだと勉強になりました!参考書などでは、探しきれない内容ばかりでとてもためになります。ありがとうございます。分からない単語がいくつかあるので調べながら自分でコードを書いて実装してみます。とても分かりやすい解説ありがとうございます。また、実装で分からないところを質問させてください。とりあえずやってみます!
guest

0

ベストアンサー

パフォーマンスは意識せずにロジックを書いたコード。

python

1from collections import defaultdict 2 3data = [[123, 12345, 4786, 1564, 7045], 4 [145, 12349, 4786, 1567, 7896], 5 [149, 12351, 4790, 1546, 8967], 6 [186, 12356, 4786, 1589, 8564], 7 [123, 12378, 4790, 1544, 8496]] 8 9d = defaultdict(int) 10for line_a in data: 11 for line_b in data: 12 if line_a is line_b: # これ別になくてもいいかな・・・ 13 continue 14 else: 15 if line_a[2] == line_b[2]: 16 if line_a[3] < line_b[3]: 17 d[line_a[0]] += 1 18 19for i, (k, v) in enumerate(sorted(d.items(), key=lambda x:x[1], reverse=True)): 20 print(i+1, k, v) 21""" => 221 123 3 232 145 1 24"""

データ量nとしてO(n^2)の計算量ですね。

投稿2018/08/01 12:45

編集2018/08/01 12:55
hayataka2049

総合スコア30933

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

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

makaron

2018/08/01 13:08

ご回答ありがとうございます!いま、出先で実行ができないので家に帰り次第実装してみます。またご連絡いたします。ありがとうございます。
hayataka2049

2018/08/01 13:27

質問文の意図がよくわからなかったので実装しただけで、実用的なパフォーマンスはありませんからご注意ください パフォーマンスを意識したコードは考えてみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問