前提・実現したいこと
Python初学者でPython3.8、Pandas0.25.3を使用しています。
ある試験の結果表(test_result.csv)から、不要な行を削除したものを成績表として転用しています。
- 試験は毎年、A(受験必須)とB(受験任意)の2種類が実施
- 成績は、Aのみの受験者はAの点数、A/B両方の受験者は高かった方の点数
つまり、Aしか受験していない人については、試験の結果=成績としてそのまま使えますが、
A/B両方を受験した人は、同年度に試験結果が2行あるため、低得点の行を削除する必要があります。
例えば17年度ですと、小島さんだけがA/B両方を受験しているため、成績表はこうなります。
|氏名|年度|点数|種類|
|:--|:--:|--:|
田中|17|82|A|
松本|17|64|A|
吉田|17|58|A|
鈴木|17|51|A|
小島|17|92|B|
この「低得点の行を削除(または高得点の行を抽出)」というところでつまづいています。
test_result.csv の内容
氏名,年度,点数,種類
田中,17,82,A
松本,17,64,A
吉田,17,58,A
鈴木,17,51,A
小島,17,88,A
小島,17,92,B
田中,18,80,A
田中,18,78,B
松本,18,66,A
吉田,18,63,A
鈴木,18,45,A
小島,18,82,A
小島,18,79,B
田中,19,78,A
田中,19,85,B
松本,19,68,A
松本,19,62,B
吉田,19,68,A
鈴木,19,48,A
小島,19,82,A
小島,19,94,B
該当のソースコード
python
1import pandas as pd 2 3df = pd.read_csv("test_result.csv",encoding="shift_jis", index_col=None) 4 5#できれば氏名・年度リストを使わずに済む方法を調べる 6p = ["田中","松本","吉田","鈴木","小島","石本"] 7y = [17,18,19] 8 9#氏名ごとに行抽出 10for person in p: 11 df_A = df[df["氏名"] == person] 12 #そこから年度ごとに行抽出することで、部分重複行を特定 13 for year in y: 14 df_B = df_A[df_A["年度"] == year] 15 #部分重複行数がなければそのまま成績表に使えるのでパス 16 if len(df_B) <= 1: 17 pass 18 else: 19 #点数が小さい方のインデックスを取得して、当インデックスの行を削除 20 print([df_B["点数"].idxmin()])#うまく行かなかったのでprintで確認 21 22 for i in [df_B["点数"].idxmin()]: 23 df_new = df.drop(index=i) 24 df_new.to_csv("aaa.csv",encoding="shift_jis") 25 26#[7] 27#[13] 28#[16] 29#[4] 30#[12] 31#[19] 32#結果、aaa.csvではindex=19の行のみ削除 33
以上を踏まえ、ご質問が2点あります。
初学者につき、理解に不足や誤認があると思いますので、ご指摘宜しくお願いします。
まず、吐き出されたcsvでindex=19の行しか削除されていないのは、削除したい行のindexが
[7][13]というように別個のリストに格納されているため、最後に部分重複行としてヒットした
index=19だけにdropが適用された、ということかなあと思っています。
そしてその原因は、部分重複行を抽出するプロセスでfor person in p:というfor文を使ったため、
と思っています。
また、indexのリストを[7,13,16,・・・]と1つのリストに格納できれば、dropすれば成績表として
吐き出すことができるのではないかと思っています。
以上の結果、
for文を使わずに部分重複行を抽出する方法が思い浮かばない ⇒
for文を使った上で、削除したいindexを1リストに格納する方法が分からない ⇒ 詰み
となってしまったところです。
そこで「for文で部分重複行を抽出した上で、削除したいindexを1リストに格納する」という
方法自体は可能なのでしょうか。可能であればどう修正すれば良いでしょうか。
また、可能だけどもっと良い方法があるよというアドバイスを頂けないでしょうか。
二点目に、上記コードでは部分重複行を抽出するため、予め氏名・年度をn,yでリスト化しています。
これは部分重複行の抽出方法として他に思い浮かばなかったための苦肉の策で(というのも、
実際の受験者は約70名、内、約1割が毎年入れ替わります)、あまり効率的ではありません。
そこでリストを使わず部分重複行を抽出する方法があれば、併せてアドバイス頂けると嬉しいです。
以上、長文お読み頂きありがとうございました。宜しくお願い致します。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/27 06:03
2019/12/27 06:06
2019/12/27 06:52
2019/12/27 07:52
2019/12/27 08:03
2019/12/27 08:03