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

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

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

Pythonistaは、iOS上でPythonプログラミングができる開発アプリです。さらに、Pythonの関数・変数などを自動で補完する便利なコードエディタや、PythonスクリプトをiOS上で多様な形で機能させる各種機能も内包しています。

Python 3.x

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

Python

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

Q&A

解決済

1回答

1026閲覧

defで関数を作成しようとした際のValue Error

Pablito

総合スコア71

Pythonista

Pythonistaは、iOS上でPythonプログラミングができる開発アプリです。さらに、Pythonの関数・変数などを自動で補完する便利なコードエディタや、PythonスクリプトをiOS上で多様な形で機能させる各種機能も内包しています。

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/04/13 04:16

前提・実現したいこと

ある通販サイトの購買データを使って
RFM分析をしたいと考えております。

実データの加工を終え、
できた商品合計金額、最後に購入してからの日数、購入回数の
カラムでできたdataframeを作ったため、
そこから各項目の数値を条件に応じてランク分けしたいです。

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

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-15-e7bf5ddc856d> in <module> 13 return 5 14 ---> 15 rfm['金額ランク'] = rfm['合計金額'].apply(money) 16 rfm.head() c:\users\lib\site-packages\pandas\core\frame.py in apply(self, func, axis, raw, result_type, args, **kwds) 7766 kwds=kwds, 7767 ) -> 7768 return op.get_result() 7769 7770 def applymap(self, func, na_action: Optional[str] = None) -> DataFrame: c:\users\lib\site-packages\pandas\core\apply.py in get_result(self) 183 return self.apply_raw() 184 --> 185 return self.apply_standard() 186 187 def apply_empty_result(self): c:\users\lib\site-packages\pandas\core\apply.py in apply_standard(self) 274 275 def apply_standard(self): --> 276 results, res_index = self.apply_series_generator() 277 278 # wrap results c:\users\lib\site-packages\pandas\core\apply.py in apply_series_generator(self) 288 for i, v in enumerate(series_gen): 289 # ignore SettingWithCopy here in case the user mutates --> 290 results[i] = self.f(v) 291 if isinstance(results[i], ABCSeries): 292 # If we have a view on v, we need to make a copy because <ipython-input-15-e7bf5ddc856d> in money(a) 1 def money(a): ----> 2 if a < 1000: 3 return 0 4 if (1000 <= a) & (a < 2000): 5 return 1 c:\users\lib\site-packages\pandas\core\generic.py in __nonzero__(self) 1440 @final 1441 def __nonzero__(self): -> 1442 raise ValueError( 1443 f"The truth value of a {type(self).__name__} is ambiguous. " 1444 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

データの中身

合計金額 最後に購入してからの日数 購入回数 sum <lambda> len 会員ID 100 2674 169 days 1 101 19760 98 days 3 103 2674 167 days 1 109 7904 56 days 3 11 2674 211 days 1 <class 'pandas.core.frame.DataFrame'> Index: 290 entries, 100 to 99 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 (合計金額, sum) 290 non-null int64 1 (最後に購入してからの日数, <lambda>) 290 non-null timedelta64[ns] 2 (購入回数, len) 290 non-null int64 dtypes: int64(2), timedelta64[ns](1) memory usage: 9.1+ KB

該当のソースコード

Python

1def money(a): 2 if a < 1000: 3 return 0 4 if (1000 <= a) & (a < 2000): 5 return 1 6 if (2000 <= a) & (a < 3000): 7 return 2 8 if (3000 <= a) & (a < 4000): 9 return 3 10 if (4000 <= a) & (a < 5000): 11 return 4 12 if a >= 5000: 13 return 5 14 15rfm['金額ランク'] = rfm['合計金額'].apply(money)

試したこと

こちらのサイトを参考にカッコ等を試してみましたが、
全て同じエラーが返ってきました。。
https://qiita.com/stokes/items/157f7ab737c5ded26832

助言を頂けますと幸いでございます。

何卒宜しくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

rfmというデータフレームをどうやって作ったかは書かれていませんが、カラムがMultiIndexになっているように見えます。

そのため、rfm['合計金額']はSeriesではなくDataFrameになるので、DataFrame.applyが呼ばれることになり、money()には単一の値ではなくSeriesが渡されて、想定外の動作になっています。

やりたいことはこうではないでしょうか。

python

1rfm['金額ランク'] = rfm[('合計金額', 'sum')].apply(money)

もしくは

python

1rfm.columns = rfm.columns.droplevel(1) 2rfm['金額ランク'] = rfm['合計金額'].apply(money)

とかで、MultiIndexを解除して実行しましょう。

上記回答とは直接関係ないですが、money()の中で、

  • &andが正しいです。(&はビット演算)
  • 順番にreturnしているので、2番目以降のifの1000 <= aとか2000 <= aは不要。

投稿2021/04/13 05:55

編集2021/04/13 05:57
bsdfan

総合スコア4794

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

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

Pablito

2021/04/13 06:05

bsdfanさま ご回答ありがとうございます! 見事に解決致しました。 そもそもMultiIndexだったことが問題だったんですね。。 演算子の使い方なども参考になりました。 誠にありがとうございます。
bsdfan

2021/04/13 06:38

ややこしいですが、booleanのSeriesやDataFrameの論理演算では&や|を使います。 このあたりは使いながら理解してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問