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

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

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

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

Q&A

解決済

2回答

1613閲覧

[python] 行数の多いデータフレームで重複する行の行番号を効率よく出力する方法が分からず困っています

mini1988

総合スコア56

Python

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

0グッド

3クリップ

投稿2020/09/23 19:06

編集2020/09/23 20:12

困っていること

手持ちのデータフレームにおいて、ある行のデータセットが他の行のデータセットと重複している場合が散見され、かつデータ数も2000行以上と、かなり多い状況にあります。

今、私が実現したいことは、

たとえば、
10行目が 100行目,200行目,300行目と重複している
20行目が 700行目,800行目,900行目と重複している
のであれば、以下のように返ってくることを期待しています。

[[10,[100,200,300],
[20,[700,800,900]]

上記のことを実現させるために、自分でもfor文で回して作ってみたのですが、データフレームの行数が2000行以上あるので、異常に時間がかかっており、for文以外のもっと効率的に期待した結果を返す方法を知りたく思っています。どなたかお分かりの方、ご教授いただければ幸いです。

私が書いたコード

ちなみに、以下のようなコードを書いたのですが、異常に時間がかかって困っています。何か効率的に重複する行番号を出力する良い方法があれば教えていただきたいです。

results=[] cnt=0 err=[] for i in list(df[df.duplicated(keep=False)].index): tmp=[] for k in list(df[df.duplicated(keep=False)].index): if i!=k: if k not in err: if list(df.iloc[i,:])==list(df.iloc[k,:]): tmp.append(k) err.append(k) cnt+=1 err.append(i) if len(tmp)>0: results.append([i,tmp])

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

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

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

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

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

jeanbiego

2020/09/23 23:12

列数はいくつあるのでしょうか。
mini1988

2020/09/23 23:47

列数は、ざっと200くらいあります。
jeanbiego

2020/09/24 00:13

ありがとうございます。 でも、すでにtoast-uzさんが処理速そうなコードで回答されてますね。
guest

回答2

0

groupbyを使ったら、もう少し簡単に書けそうです。
(前半、toast-uzさんのコードを使っています)

python

1import pandas as pd 2 3df = pd.DataFrame([ 4 [1, 2, 3, 4], 5 [1, 2, 3, 5], 6 [1, 2, 3, 6], 7 [1, 2, 3, 7], 8 [1, 3, 3, 4], 9 [1, 2, 3, 4], 10 [1, 2, 3, 4], 11 [1, 3, 3, 4] 12 ]) 13 14# 重複している行を全て抽出 15df_duplicated_all = df[df.duplicated(keep=False)] 16 17# 全カラムを使ってgroupbyして、それぞれのグループのインデックスをリストで抽出 18groups = df_duplicated_all.groupby(list(df_duplicated_all.columns), as_index=False) 19output = [list(d.index) for _, d in groups] 20 21print(output) 22# [[0, 5, 6], [4, 7]] 23 24# 先頭と、それ以降をわける 25output = [[l[0], l[1:]] for l in output] 26print(output) 27# [[0, [5, 6]], [4, [7]]]

投稿2020/09/24 01:31

編集2020/09/24 01:38
bsdfan

総合スコア4599

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

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

mini1988

2020/09/24 02:00

早速回答いただきまして、ありがとうございます。提供していただいたコードを動かして、やりたいことがかなり迅速にできるようになりました。本来はベストアンサーをお付けしたかったのですが、お許しください。素敵なコードをありがとうございます。
toast-uz

2020/09/24 03:06

お見事です!
guest

0

ベストアンサー

こんなのでいかがでしょうか?

Python

1import pandas as pd 2 3df = pd.DataFrame([ 4 [1, 2, 3, 4], 5 [1, 2, 3, 5], 6 [1, 2, 3, 6], 7 [1, 2, 3, 7], 8 [1, 3, 3, 4], 9 [1, 2, 3, 4], 10 [1, 2, 3, 4], 11 [1, 3, 3, 4] 12 ]) 13 14# 重複している行を全て抽出 15df_duplicated_all = df[df.duplicated(keep=False)] 16# 重複している行の先頭行だけ抽出 17df_duplicated_first = df_duplicated_all[~df_duplicated_all.duplicated()] 18# 重複している行の先頭行以外を抽出 19df_duplicated_rest = df_duplicated_all[df_duplicated_all.duplicated()] 20 21output = [] 22# 重複している行の先頭行を、1行ずつ処理 23for index_first, row in df_duplicated_first.iterrows(): 24 # このループで注目している先頭行と、同じ行を先頭行以外から抽出 25 df_duplicated_rest_for_this_index = df_duplicated_rest[ 26 (df_duplicated_rest == row).astype(int).min(axis=1).astype(bool)] 27 # 結果のindexをリストに加える 28 output.append([index_first, df_duplicated_rest_for_this_index.index.values.tolist()]) 29 30print(output)

投稿2020/09/23 23:41

toast-uz

総合スコア3266

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

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

mini1988

2020/09/24 01:58

早速回答いただきまして、ありがとうございます。提供していただいたコードを動かして、やりたいことがかなり速くできるようになりました。感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問