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

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

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

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

Q&A

解決済

1回答

736閲覧

CSV出力プログラムを作るにあたってSettingWithCopyWarningの解決したいのですが上手くできません。

ruruya

総合スコア1

Python

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

0グッド

0クリップ

投稿2023/04/01 21:38

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 日本株の全銘柄の銘柄コード、銘柄名、業種、株価を表示するCSVを出力するためのコードを作りたいです。

前提

ここに質問の内容を詳しく書いてください。

今まで使っていた株式投資のデータ提供サイトが閉鎖してしまったため、自分で似たようなのを作ろうと久々にPythonの教本を手に取りながらコードを組んでいます。

 日本株の全銘柄の銘柄コード、銘柄名、業種はJPXのサイトのCSVをrequestsで取得し、そのCSVを主軸として別のサイト「http://mujinzou.com/index.htm」から全銘柄の株価等のCSVをダウンロードし、ローカルに格納してからPythonで読み込み、株価、それとできれば出来高の列をJPXから取得したCSVに移植し、移植したCSVをローカルに出力したいのですが、出力されたCSVには株価が約160/3800ほど空白となっています。

エラーメッセージから隠れ連鎖?chained indexingとやらが原因らしいというのは分かったのですが、解決策を調べてもいまいち理解できません。

解決法は.locとやらを使う、もしくは.copyを使う、とのことですがどっちもうまく当てはめることができなくてかれこれ4時間経ち、もう質問した方が早いかな、と考えた次第です。

なお、CSVをローカルにダウンロードしているところが無駄かなとは考えましたが、そこは見逃していただけると幸いです。
Pythonの基準の文字コードはutf-8ですが、過去に使っていたCSVの読み込み、出力ではshift_jisを使っています。教本の通りにコードを記述したためです。
そして今回のコードの最終行のCSV出力では文字コードにCP932を使用していますが、これはshift_jis、およびutf-8のどちらも文字化けを熾したためであって適当に使っているわけではありません。

拙い文章、拙いコードで申し訳ないのですが御教授頂けないでしょうか?

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

エラーメッセージ ```SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy codes["終値"] = df3["終値"] ### 該当のソースコード ```ここに言語名を入力 Python ソースコード ```import requests import pandas as pd #上場銘柄一覧取得 url = "https://www.jpx.co.jp/markets/statistics-equities/misc/tvdivq0000001vg2-att/data_j.xls" r = requests.get(url) with open('data_j.xls', 'wb') as output: output.write(r.content) #データフレーム作成 stocklist = pd.read_excel("./data_j.xls") stocklist.loc[stocklist["市場・商品区分"]=="市場第一部(内国株)", ["コード","銘柄名","33業種コード","33業種区分","規模コード","規模区分"] ] #ETF等を除く codes = stocklist[(stocklist['市場・商品区分'] == 'プライム(内国株式)') | (stocklist['市場・商品区分'] == 'スタンダード(内国株式)') | (stocklist['市場・商品区分'] == 'グロース(内国株式)')] len(codes) '''全株価データ取得''' #CSV読み込み df=本日日付 df = pd.read_csv("C:\\Users\\□□□□□\\OneDrive\\デスクトップ\\□□□□□\\全株価データ\\20230329全株価データ.CSV", encoding="Shift_Jis") #ETF等を除く df3 = df[(df['上場区分'] == '東証P') | (df['上場区分'] == '東証S') | (df['上場区分'] == '東証G')] #株価データから終値の列を抽出 df3["終値"] #新規列の追加、削除 codes["終値"] = df3["終値"]      ←ここです。こいつでcodesにdf3の終値(株価)を移植してるのに空白欄ができてしまいます。 codes = codes.drop("33業種コード", axis=1) codes = codes.drop("17業種コード", axis=1) codes = codes.drop("規模コード", axis=1) #CSVを出力 codes.to_csv("C:\\Users\\□□□□□\\OneDrive\\デスクトップ\\□□□□□\\整形株価データ\\jpx_code.csv", encoding = "CP932") ### 試したこと .loc[codes["終値"]] = df3["終値"]を代入 copyについては参考にしたサイトでは条件がどうのと良く分かりませんでした。 ### 補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

meg_

2023/04/02 04:12

リンクの設定が間違っていますので直した方が良いかと思います。(余分な文字列が付いています)
meg_

2023/04/02 04:15

df3 = df[(df['上場区分'] == '東証P') | (df['上場区分'] == '東証S') | (df['上場区分'] == '東証G')].copy() としたらエラーは無くなりますか?
bsdfan

2023/04/02 13:07

SettingWithCopyWarning は、copy() をつけると消せると思います。 空白が入るのはそれとは違う理由です。単なる代入ではなく、なんらかの列をキーにして更新したいとかだったりしませんか?
ruruya

2023/04/02 14:27

meg_さん >df3 = df[(df['上場区分'] == '東証P') | (df['上場区分'] == '東証S') | (df['上場区分'] == '東証G')].copy() としたらエラーは無くなりますか?  とのことですが、試してもエラーは無くなりませんでした。 bsdfanさん >空白が入るのはそれとは違う理由です。単なる代入ではなく、なんらかの列をキーにして更新したいとかだったりしませんか?  csvの列を1列丸ごと移植・更新しようとしています。キー設定をして更新、というわけではありません。
ruruya

2023/04/02 14:31

追記 新規列追加・削除コードに dfa["終値"] = df3["終値"].copy() と記述に.copy()を加えて実行すると警告は消えました。 しかし移植した値が虫食い状態になっています。
bsdfan

2023/04/03 23:43

> 1列丸ごと移植・更新しようとしています。 codes["終値"] = df3["終値"].to_numpy() のように、ndarray にして代入するといいです。 Series で代入するとインデックスが一致しているところにしか値が入りません。 (これで解決するかはわかりません)
guest

回答1

0

ベストアンサー

以下の行を
#--------------------------------------------------
#株価データから終値の列を抽出
df3["終値"]

#新規列の追加、削除
codes["終値"] = df3["終値"]      
#------------------------------------------------------
以下のように変えてみては、どうでしょうか。
#----------------------------------------------
#株価データから終値の列を抽出
df3 = df3[["銘柄コード","終値"]]
#銘柄コードをキーにしてマージする
codes = codes.merge(df3,left_on="コード",right_on="銘柄コード",how="inner")
#--------------------------------------------
20230329全株価データ.CSVのヘッダ行の定義が不明なので、銘柄コードの列名は"銘柄コード"としました。
違っている場合は、適宜、読み替えてください。

投稿2023/04/03 07:51

tatsu99

総合スコア5470

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

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

ruruya

2023/04/05 12:09

ありがとうございます! 教えて頂いたコードに変えてみたら上手くいきました! やはり初心者向けの本だけではコードを書くには心もとないのですかね…… マージというものを貴方様のアンサーを読んで初めて知りました。 これからも少しずつ勉強しようと思える経験になりました。 本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問