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

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

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

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

Q&A

解決済

1回答

1413閲覧

データフレームを並べ替えて、縦方向に連結させたい

tomoysh

総合スコア42

Python

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

0グッド

0クリップ

投稿2021/11/05 03:23

編集2021/11/07 06:31

前提・実現したいこと

以下のデータフレームdf1,df2があります。

python

1 2(df1) 3# 身長 体重 成績 過去成績 4# A 160 70 3 2 5# B 165 55 2 3 6# C 150 50 1 1 7 8(df2) 9# 身長 体重 成績 過去成績 10# A 162 46 1 3 11# B 168 58 3 2 12# C 170 60 2 1 13 14

実現したいことはdf1,df2をそれぞれ成績順にソートして一つのデータフレームにすることです。
concat()を使って実現させようと思いましたが、結合させるdfが多数あるため他の方法を模索しています。

python

1(df1+df2) 2# 身長 体重 成績 過去成績 3# C 150 50 1 1 4# B 165 55 2 3 5# A 160 70 3 2 6# A 162 46 1 3 7# C 170 60 2 1 8# B 168 58 3 2

最終的には上記のようにデータフレームを形成するのが目的です。df1の中で成績順にソートし、df2の中で成績順にソートして一つのdfにしたいと思っています。何かいい方法があれば教えてください。

追記

何度も申し訳ありません。教えていただいた方法で実装しようと試みたのですが、色々と自分の技量が足らず、実装できませんでした。「ループ1回毎にリストに追加」という流れは理解できたのですが、どのようにコードに適用し、記述すれば実装できるのかがいまだに理解できておりません。
以下が現在のコードでどのように変更すれば、実現できるのか、教えていただけないでしょうか。

python

1rank_list = [] 2height_list = [] 3weight = [] 4 5for i in soup_html: 6 content = i.find_all(class_='Num') 7 for i in content: 8 rank = i.text 9 rank = rank.replace('\n', '') 10 rank_list.append(rank) 11 12for i in soup_html: 13 content = i.find_all(class_='height') 14 for i in content: 15 height = i.text 16 height = height.replace('\n', '') 17 height_list.append(height) 18 19for i in soup_html: 20 content = i.find_all(class_='weight') 21 for i in content: 22 weight = i.text 23 weight = weight.replace('\n', '') 24 weight_list.append(weight) 25 26 27df = pd.DataFrame() 28df['成績'] = rank_list 29df['身長'] = height_list 30df['体重'] = weight_list 31

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

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

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

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

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

guest

回答1

0

ベストアンサー

pandas.concat() を使います。

python

1import pandas as pd 2 3pd.set_option('display.unicode.east_asian_width', True) 4 5df1 = pd.DataFrame({ 6 '身長': [160, 165, 150], 7 '体重': [ 70, 55, 50], 8 '成績': [ 3, 2, 1], 9 '過去成績': [ 2, 3, 1], 10}, index = ['A', 'B', 'C']) 11 12df2 = pd.DataFrame({ 13 '身長': [162, 168, 170], 14 '体重': [ 46, 58, 60], 15 '成績': [ 1, 3, 2], 16 '過去成績': [ 3, 2, 1], 17}, index = ['A', 'B', 'C']) 18 19df3 = pd.concat(i.sort_values('成績') for i in (df1, df2)) 20 21print(df3) 22# 23 身長 体重 成績 過去成績 24C 150 50 1 1 25B 165 55 2 3 26A 160 70 3 2 27A 162 46 1 3 28C 170 60 2 1 29B 168 58 3 2

追記

以下が現在のコードでどのように変更すれば、実現できるのか

以下、かなり冗長ですが書き換えの一例として参考にして下さい(動作保証はありません)。

python

1df_list = [] 2for s in soup_html: 3 rank_list = [] 4 height_list = [] 5 weight = [] 6 df = pd.DataFrame() 7 8 content = s.find_all(class_='Num') 9 for i in content: 10 rank = i.text 11 rank = rank.replace('\n', '') 12 rank_list.append(rank) 13 df['成績'] = rank_list 14 15 content = s.find_all(class_='height') 16 for i in content: 17 height = i.text 18 height = height.replace('\n', '') 19 height_list.append(height) 20 df['身長'] = height_list 21 22 content = s.find_all(class_='weight') 23 for i in content: 24 weight = i.text 25 weight = weight.replace('\n', '') 26 weight_list.append(weight) 27 df['体重'] = weight_list 28 29 # for i in soup のループが1回完了する毎にリストに追加します 30 df_list.append(df.sort_values('成績')) 31 32# 全て取得したら縦に連結 33df_all = pd.concat(df_list)

投稿2021/11/05 03:40

編集2021/11/07 14:20
melian

総合スコア20655

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

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

tomoysh

2021/11/05 06:47

コメントありがとうございます。 この方法だとforの部分にデータフレームの個数分df3,df4等と記述しなければならないのでしょうか? 結合したいdfが1000個近くあります。 あるいはデータフレームを作る際にデータフレーム毎にソートして、for ループでdf1,df2,df3.....df1000などと、縦方向に追加していくというような手法は可能なのでしょうか? 可能であれば手法を教えていただきたく思います。
melian

2021/11/05 06:50

データフレームを作成する手順は、例えば CSV ファイルが1000個くらいあって、それらを read_csv() などでデータフレーム化しているのでしょうか?
tomoysh

2021/11/05 07:00

beautifulsoupでスクレイピングしたデータからデータフレーム化しています。 pd.DataFrame()で作成しそこにデータを追加する手法で行っています。
melian

2021/11/05 07:06 編集

そうですね、それではデータフレームのリスト(例えば df_list という名前)を作って追加していくのはどうでしょうか。 df_list = [] df_list.append(スクレイピングして作ったデータフレーム) そうすれば pd.concat(i.sort_values('成績') for i in df_list) とすればよいことになります。
tomoysh

2021/11/06 06:42

昨日からその手法での実装を試みているのですが、うまくいきません。 df_list.append()のところは()に i など変数を入れてfor文で回していくということでしょうか? 具体的なコードで教えていただければ大変参考になります。
melian

2021/11/06 06:48

i などの変数ではなく個々のデータフレームを入れます。「スクレイピングしたデータからデータフレーム化」のデータフレーム化をどうやっているのか、具体的なコードを提示していただけないでしょうか? それが判ればもう少し適切なコメントができそうです。
tomoysh

2021/11/06 08:47

rank_list = [] for i in soup: content = i.find_all(class_='A') for i in content: rank = i.text rank_list.append(rank) df = pd.DataFrame() df['成績'] = rank_list 上記のような手法でDFを作成しています。身長、体重も同じ手法でlistを作成し,df['身長']=height_list df['体重']=weight_listのようにdfに追加しています。 for i in soup:でsoupを取得(ここが1000個近くある部分) そして、for i in content:でその中の成績、身長、体重を取得(この一つのcontentの中でソートしたい) このようなコードで試みています。よろしくお願いします。
melian

2021/11/06 09:13

回答に追記してみましたが、間違いがありましたら指摘して下さい。
tomoysh

2021/11/07 06:33

質問欄に現在の状況を記載しました。お力添えいただきたく思います。
tomoysh

2021/11/08 14:57

なんとか実装でき、とりあえず動く形になりました。コードが長々となっているので、さらに自分なりに知識を得てブラッシュアップしてみようと思います。 丁寧なご説明ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問