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

Q&A

解決済

2回答

194閲覧

ValueError 「cannot reindex on an axis with duplicate labels」が解決出来ない

nomsan

総合スコア6

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2025/10/29 06:36

0

0

実現したいこと

Python初心者です。よろしくお願いいたします。

pythonのデータフレームの操作で条件に該当する値がある時に新しいcolumnを
作成して計算結果を入れたいがエラーが出て実行できないです。

発生している問題・分からないこと

実行するとValue Error「cannot reindex on an axis with duplicate labels」が発生します。

エラーメッセージ

error

1cannot reindex on an axis with duplicate labels

該当のソースコード

#df    品名   購入数量   YM    Y  M  0 商品1 48.0    2024年01月 2024  01 1 商品2 520.0 2024年02月 2024  02 2 商品3 0.0    2024年03月 2024  03 3 商品4 0.0    2024年05月 2024  05 4 商品5 0.0    2024年06月 2024  06 #Mが01、02、03の時に新しいColumn fin_Y にYから1を引いた数値を入れたいです。 df_x = df last_f_year = ["01","02","03"] fin_cond = df_x["M"].isin(last_f_year) df_x.loc[fin_cond,"fin_Y"] = df_x["Y"] - 1 #ここでエラーになります #欲しい結果    品名   購入数量   YM    Y  M  fin_Y 0 商品1 48.0    2024年01月 2024  01  2023 1 商品2 520.0 2024年02月 2024  02  2023 2 商品3 0.0    2024年03月 2024  03  2023 3 商品4 0.0    2024年05月 2024  05 4 商品5 0.0    2024年06月 2024  06

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

変数fin_condにはBool値が入っていますし、条件を与えずにColumnを追加して
値の追加も出来ますが、locで条件を与えるとエラーになります。
(df_x["fin_Y"] = df_x["Y"] - 1 は普通に実行できます)

補足

初歩的な質問で申し訳ありませんが、よろしくお願いいたします。

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

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

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

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

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

melian

2025/10/29 07:35 編集

Y列の値が文字列(str型)である場合は df_x.loc[fin_cond,"fin_Y"] = df_x["Y"] - 1 で、 TypeError: unsupported operand type(s) for -: 'str' and 'int' というエラーが発生します。Y列が整数(int型)である場合はエラーは発生しません。 問題のデータフレームはどの様にして作成したのでしょうか? ## 追記 df_x = df としていますが、この場合、df_x と df は同一のデータフレーム(インスタンス)になります。(shallow copy) df_x の内容を変更しても df に影響がない様にする場合は copy() メソッドを使います。 df_x = df.copy() # デフォルトは deep=True なので deep copy になります pandas.DataFrame.copy — pandas 2.3.3 documentation https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.copy.html > When deep=False, a new object will be created without copying the calling object’s data or index (only references to the data and index are copied). Any changes to the data of the original will be reflected in the shallow copy (and vice versa).
nomsan

2025/10/29 08:17

melianさん 返信、ありがとうございます。元のデータはExcelでY列はファイル名から取得しています。その為、 df["Y"] = df["Y"].astype(int) でint型に変更して計算が出来るようにしました。 最初は計算でエラーが出ているかと思っていたいので、試しに df_x["fin_Y"] = df_x["Y"] - 1 で計算が出来るので、今回質問をしたlocの部分でエラーが出ているのかと考えました。 お恥ずかしい話ですが、同一のインスタンスについて理解していなくとりあえず df_x = df にしてコピーを作成していました。今回の質問に関係ないのかも知れませんが 教えていただいた df_x = df.copy() に変更しても同一のエラー(cannot reindex~)は解消されませんでした。 他に考えられることがあれば教えていただけると幸いです。 よろしくお願いいたします。
melian

2025/10/29 08:54

こちらの環境は Python3.13.7/Pandas 2.3.3 です。以下のコードをそちらで実行してもらえますか?(こちらではエラーにはなりません) https://www.mycompiler.io/view/0UenC01e5as
nomsan

2025/10/30 04:56

melianさん 返信、ありがとうございます。 今回は他の方の回答で解決することができました。 私の質問にもう少し細かい情報を記載すればよかったと反省しています。 また何かありましたら投稿させていただきますので、 よろしければまたアドバイスをお願いいたします。 よろしくお願いいたします。
guest

回答2

0

既に解決済みなので,御参考です。

変数 fin_cond には Bool 値が入っていますし、条件を与えずに Column を追加して
値の追加も出来ますが、loc で条件を与えるとエラーになります。
(df_x["fin_Y"] = df_x["Y"] - 1 は普通に実行できます)

ということなので,loc を用いない記述例を考えてみました。

Python

1import pandas as pd 2 3pd.set_option('display.unicode.east_asian_width', True) 4 5df = pd.DataFrame({'品名': ['商品1', '商品2', '商品3', '商品4', '商品5'], 6 '購入数量': [48.0, 520.0, 0.0, 0.0, 0.0], 7 'YM': ['2024年01月', '2024年02月', '2024年03月', 8 '2024年05月', '2024年06月'], 9 'Y': ['2024', '2024', '2024', '2024', '2024'], 10 'M': ['01', '02', '03', '05', '06']}) 11df_x = df.copy() 12 13last_f_year = ['01', '02', '03'] 14fin_cond = df_x['M'].isin(last_f_year) 15df_x['fin_Y'] = [str(int(y) - 1) if fc else '' for y, fc 16 in zip(df_x['Y'], fin_cond)] 17 18print(df_x) 19# 品名 購入数量 YM Y M fin_Y 20# 0 商品1 48.0 2024年01月 2024 01 2023 21# 1 商品2 520.0 2024年02月 2024 02 2023 22# 2 商品3 0.0 2024年03月 2024 03 2023 23# 3 商品4 0.0 2024年05月 2024 05 24# 4 商品5 0.0 2024年06月 2024 06

また,apply() メソッドaxis=1 とともに用いると,条件も含めて下記のように記述することもできます。

Python

1df_x['fin_Y'] = df_x.apply( 2 lambda r: str(int(r['Y']) - 1) if r['M'] in ['01', '02', '03'] 3 else '', axis=1)

投稿2025/10/30 04:41

little_street

総合スコア541

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

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

nomsan

2025/10/30 05:18

little_streetさん 返信、ありがとうございます。 今回の様に条件に合う箇所に値を入力するにはいつもlocを使用していましたが、 確かにapplyを選択するのもありですね。勉強になります。 確かに値の入力も問題無く動きました。 他のプログラムでも試してみます。 ありがとうございました。
guest

0

ベストアンサー

python

1df_x.loc[fin_cond,"fin_Y"] = df_x["Y"] - 1

左辺と右辺の長さ(インデックス)が不一致なのが原因です。
インデックスが不一致の場合、中で reindex してインデックスを一致させてから代入する処理をしますが、元のインデックスに重複する要素があってreindexできないというエラーです。

下記のようにして、長さ(インデックス)をそろえてやれば動くと思います。

python

1df_x.loc[fin_cond,"fin_Y"] = df_x.loc[fin_cond, "Y"] - 1

質問の例で挙げられているもののようにインデックスが重複していない場合は、エラーが出ないはずです。
インデックスが重複するケースとしてはpd.concatしたものとかが考えられますが、その場合は pd.concat(..., ignore_index=True)df_x = df_x.reset_index(drop=True) するのがいいかもしれません。

投稿2025/10/30 01:00

bsdfan

総合スコア4954

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

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

nomsan

2025/10/30 04:50

bsdtanさん 回答ありがとうございました。長さ(インデックス)を揃える方法とconcatの引数に インデックスの操作を追加する方法、両方とも無事に動くことを確認出来ました。 ご指摘の通り、複数のExcelをconcatで結合していてインデックスに重複がありました。 本当に助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問