質問するログイン新規登録
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

391閲覧

for文を使って、データフレーム内の特定の列を抽出して回し、CSVに書き出したい。

syoh0335

総合スコア5

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/08/10 03:39

編集2023/08/10 06:27

0

0

実現したいこと

データフレームの['SC']という列の値毎のCSVファイルを書き出したい。

前提

xlsxファイルをデータフレームに読み込んだ後に、「SC」という列の値をfor文で回して、ファイルを分けるシステムを作っています。

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

一番最初に返ってくる値(CSV)は中身があるのですが、2回目以降から中身がなく、以下のようなエラーメッセージが返ってきます。

エラーメッセージ
Empty DataFrame
Columns: [SC, 名称, 市場, 業種, 日付, 株価, 25日移動平均線, 75日移動平均線]
Index: []

該当のソースコード

import pandas as pd df = pd.read_excel('〇〇.xlsx', sheet_name = 'Sheet1') meigara_list = df['SC'].to_list() #print(type(meigara_list)) #print(meigara_list) for meigara in meigara_list: filter_sc = df['SC'] == meigara df = df[filter_sc] df['25日移動平均線'] = df['株価'].rolling(window=25).mean().round(1) df['75日移動平均線'] = df['株価'].rolling(window=75).mean().round(1) df = df.sort_values('日付', ascending=False) print(df) df.to_csv('data/result_all_25_75_{}.csv'.format(meigara)) if meigara == 1376: break

python

試したこと

listの中身はprint文で確認済です。
最初は「meigara_list」というリストにせず、そのままfor文で回していたのですが、調べてたらリストの方が良さそうでしたので、今はリストにしてます。

for文の中身の問題ではないかと思っているのですが、私の実力じゃ解決に至らずでご教授いただければ幸いです。
宜しくお願い致します。

補足情報(FW/ツールのバージョンなど)

python3.9
pycharm2022.2.3

●追記

import pandas as pd

df = pd.read_excel('〇〇.xlsx', sheet_name = 'Sheet1')

for meigara in set(df['SC'].to_list()):
filter_sc = df['SC'] == meigara
df2 = df[filter_sc].copy()
print(df2)

df2['25日移動平均線'] = df2['株価'].rolling(window=25).mean().round(1) df2['75日移動平均線'] = df2['株価'].rolling(window=75).mean().round(1) df2 = df2.sort_values('日付', ascending=False) # print(df) df2.to_csv('data/result_all_25_75_{}.csv'.format(meigara)) if meigara == 1376: break

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

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

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

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

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

meg_

2023/08/10 03:50

> 以下のようなエラーメッセージが返ってきます。 エラーメッセージではなく単に「print(df)」の結果ではありませんか? エラーが発生しているか否かでどの辺りを見るかも変わってきます。何らかのエラーは発生しているのでしょうか?ご確認ください。
meg_

2023/08/10 03:51

'〇〇.xlsx'のサンプルデータをテキストで提示いただけませんか?
syoh0335

2023/08/10 04:18

meg_さん ご無沙汰しております。試したところprint文の結果でした。 下記のような表のデータです。 量が膨大な為、一部しか書いてないのですが、こちらで判断可能でしょうか? SC 名称 市場 業種 日付 株価 1 日経平均株価(日経225) 東証 株価指数 20230809 32204.33 2 TOPIX(東証株価指数) 東証 株価指数 20230809 2282.57 1301 極洋 東証PR 水産・農林 20230809 3770 1332 ニッスイ 東証PR 水産・農林 20230809 752.4 1333 マルハニチロ 東証PR 水産・農林 20230809 2448 1375 雪国まいたけ 東証PR 水産・農林 20230809 922 1376 カネコ種苗 東証ST 水産・農林 20230809 1423
syoh0335

2023/08/10 04:22

追加で掲載いたします。 SC 名称 市場 業種 日付 株価 1 日経平均株価(日経225) 東証 株価指数 20230809 32204.33 2 TOPIX(東証株価指数) 東証 株価指数 20230809 2282.57 1301 極洋 東証PR 水産・農林 20230809 3770 1332 ニッスイ 東証PR 水産・農林 20230809 752.4 1333 マルハニチロ 東証PR 水産・農林 20230809 2448 1375 雪国まいたけ 東証PR 水産・農林 20230809 922 1376 カネコ種苗 東証ST 水産・農林 20230809 1423 1 日経平均株価(日経225) 東証 株価指数 20220801 27993.35 2 TOPIX(東証株価指数) 東証 株価指数 20220801 1960.11 1301 極洋 東証PR 水産・農林 20220801 3650 1332 日本水産 東証PR 水産・農林 20220801 597 1333 マルハニチロ 東証PR 水産・農林 20220801 2491 1375 雪国まいたけ 東証PR 水産・農林 20220801 974 1376 カネコ種苗 東証ST 水産・農林 20220801 1647 1 日経平均株価(日経225) 東証 株価指数 20220802 27594.73 2 TOPIX(東証株価指数) 東証 株価指数 20220802 1925.49 1301 極洋 東証PR 水産・農林 20220802 3615 1332 日本水産 東証PR 水産・農林 20220802 595 1333 マルハニチロ 東証PR 水産・農林 20220802 2458 1375 雪国まいたけ 東証PR 水産・農林 20220802 958 1376 カネコ種苗 東証ST 水産・農林 20220802 1625
guest

回答1

0

ベストアンサー

df = df[filter_sc]で元のdfが上書きされているためです。
df2 = df[filter_sc].copy()のように別のdf2で(念のためコピーして)処理するとよいでしょう。
あと、リストそのままではなくsetにして重複を取り除いたものをforで回したほうが目的に合っていると思います。

Python

1import pandas as pd 2 3df = pd.DataFrame({'SC':[1,1,2],'Val':[1,2,3]}) 4 5for meigara in set(df['SC'].to_list()): 6 filter_sc = df['SC'] == meigara 7 df2 = df[filter_sc].copy() 8 print(df2) 9 10# あるいはたんに以下でよい 11for meigara, df2 in df.groupby('SC'): 12 print(meigara) 13 print(df2)

投稿2023/08/10 04:29

編集2023/08/10 05:01
can110

総合スコア38350

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

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

syoh0335

2023/08/10 04:44

can110さん 回答ありがとうございます。 まだ理解に及ばないのですが、dfを「'SC'」の数、用意するという事でしょうか? df = df[filter_sc] df2 = df[filter_sc].copy() df3 = df[filter_sc].copy() . . .
can110

2023/08/10 05:00

いえ。ループ中の修正です。コード例を追記しました。
syoh0335

2023/08/10 05:40

差し替えて色々試してみたのですが、以下のようになっております。 ①SC毎にファイルが作られるが、足りない。 ②作られたファイルの中身に別のSCの値が混ざっている。 ③移動平均の値が計算されていない。 大きく分けるとこの3つの事が起きています。 私のコードミスかもしれないので、コードも掲載します。 ご確認の程宜しくお願い致します。 import pandas as pd df = pd.read_excel('〇〇.xlsx', sheet_name = 'Sheet1') for meigara in set(df['SC'].to_list()): filter_sc = df['SC'] == meigara df2 = df[filter_sc].copy() print(df2) df['25日移動平均線'] = df2['株価'].rolling(window=25).mean().round(1) df['75日移動平均線'] = df2['株価'].rolling(window=75).mean().round(1) df = df.sort_values('日付', ascending=False) # print(df) df.to_csv('data/result_all_25_75_{}.csv'.format(meigara)) if meigara == 1376: break
can110

2023/08/10 06:08

> ①SC毎にファイルが作られるが、足りない。 具体的にどのようなデータでどういう結果(何が足りない)になっているのかが不明です。 ちなみにsetの中身は順不同であることは認識されていますか? > ②作られたファイルの中身に別のSCの値が混ざっている。 コードは問題ないと思われます。 > ③移動平均の値が計算されていない。 別の問題なので別途質問を立てるべきと思います。
TakaiY

2023/08/10 06:12 編集

横からすみません コードに以下の問題があります。 for文の中で、新たにdf2という名前で、目的のSCのものだけ抽出したDadaFrameを作っていますから、本来は、そのdf2を使って処理をしなければなりません。ですが、コードを見ると、途中からdfに対する操作になっていて、最終的にdfをcsvに出力しています。 for文の中の操作はすべてdf2に対して行なう必要があります。 (インデント無くなっているので、想定どおりだとしたらですが。) (修正したコードを提示するなら、ここではなく、質問を編集して追記したほうがいいでしょう)
syoh0335

2023/08/10 06:15

申し訳ありません。言葉足らずでした。 ③に関しては別途そのように致します。 ①ですが、setの中身が順不同というのは知りませんでした。申し訳ありません。 例えばSCの値が10個あったとして、for文を回しているので、to_CSVでも10個CSVファイルが作られると思うのですが、5個しか作られていないような結果になっております。
syoh0335

2023/08/10 06:30

TakaiYさん コメントありがとうございます。 アドバイスを元にdf2と変更していなかった箇所を訂正した結果、上記で挙げていた②③の問題が解決できました。 ありがとうございます。
syoh0335

2023/08/10 06:49

みなさまアドバイスなどありがとうございました。 setをlistに戻したら、ちゃんと出力できました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問