🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

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

pandas

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

Q&A

解決済

2回答

935閲覧

データフレームの集計を高速化したい

gogotowel

総合スコア9

Python 3.x

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

pandas

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

0グッド

1クリップ

投稿2021/01/31 03:01

データフレーム内の要素の出現数を集計したいと考えております。

このようなデータフレームを

dataframe

1日付 おにぎりの具 22020/9/1 梅干し 32020/10/1 サケ 42020/11/1 タラコ 52020/12/1 タラコ 62021/1/1 梅干し 7

このようにしたい。
resampleで期間ごとに集計できる形式にするのが目的です。

dataframe

1日付     おにぎりの具  梅干し サケ  タラコ 22020/9/1  梅干し      1 32020/10/1  サケ        1 42020/11/1  タラコ          1 52020/12/1  タラコ          1 62021/1/1 梅干し      1

そこでdf.iterrowsで回して次の通り処理をしてるのですが、
速度面で難があります。

python

1gu = ["梅干し","サケ","タラコ"] 2for g in gu: 3 for i in df.iterrows(): 4 df.loc[df["おにぎりの具"] == g, g] = 1

そこでmapメソッドを使って、次の通り関数を適用させることで
解消しようとしてますが、エラーとなります。
エラーの原因がどうしてもわかりません。

python

1s = df["おにぎりの具"] 2 3def onigiri_map(): 4 onigiri_str = ["梅干し","サケ","タラコ"] 5 for oni in onigiri_str: 6 df.loc[df["おにぎりの具"]==oni,oni] = 1 7 8s = s.map(onigiri_map()) 9 10TypeError: 'NoneType' object is not callable

どうしてもmapにこだわる理由もないのですが、原因等分かればと思います。
分かりにくい説明となりましたが、どうぞご回答よろしくお願いします。

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

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

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

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

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

guest

回答2

0

処理としての正解は「get_dummiesを使う」だと思いますが、質問文のコードの問題点について。

Seriesのmapの引数には関数オブジェクトを指定します。ですから、()を付けてonigiri_mapを呼び出してはいけません。onigiri_mapの返り値を指定することになり、返り値はNoneなので、件のエラーの原因になります。

さらに言えば、mapに渡す関数オブジェクトは引数を一つ取らなければいけないので、()を取っただけでは別のエラーが発生します。この引数には、「おにぎりの具」の要素がひとつずつ渡されます。

細かな問題としては、df.locで1に設定した以外の「梅干し」などの列のデータはNaN(float型)になるので、1も連動して1.0(float型)になります。あらかじめ「梅干し」列を0で埋めておくなどの対策が必要でしょう。

ということで、これらを解決した(けど、おそらく使われない)コードがこちら。

Python

1import pandas as pd 2import io 3 4txt = """ 5日付,おにぎりの具 62020/9/1,梅干し 72020/10/1,サケ 82020/11/1,タラコ 92020/12/1,タラコ 102021/1/1,梅干し 11""" 12 13pd.set_option('display.unicode.east_asian_width', True) 14 15df = pd.read_csv(io.StringIO(txt), parse_dates=['日付']) 16s = df["おにぎりの具"] 17for g in s: 18 df[g] = 0 19# print(df) 20 21 22def onigiri_map(oni): 23 onigiri_str = ["梅干し", "サケ", "タラコ"] 24 if oni in onigiri_str: 25 df.loc[df["おにぎりの具"] == oni, oni] = 1 26 27 28s.map(onigiri_map) 29print(df)

result

1 日付 おにぎりの具 梅干し サケ タラコ 20 2020-09-01 梅干し 1 0 0 31 2020-10-01 サケ 0 1 0 42 2020-11-01 タラコ 0 0 1 53 2020-12-01 タラコ 0 0 1 64 2021-01-01 梅干し 1 0 0

投稿2021/01/31 03:38

Daregada

総合スコア11990

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

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

gogotowel

2021/01/31 04:47

tiitoi様のご指摘にもありましたが、関数オブジェクトの使い方を分かってなかったということですね・・・ 勉強になります。ありがとうございます。
guest

0

ベストアンサー

カテゴリ変数の OneHot表現への変換は pandas.get_dummies() で行えます。

python

1df = pd.DataFrame( 2 { 3 "日付": ["2020/9/1", "2020/10/1", "2020/11/1", "2020/12/1", "2021/1/1"], 4 "おにぎりの具": ["梅干し", "サケ", "タラコ", "タラコ", "梅干し"], 5 } 6) 7 8df2 = pd.get_dummies(df, columns=["おにぎりの具"], prefix="", prefix_sep="") 9df2["おにぎりの具"] = df["おにぎりの具"] 10print(df2)
日付サケタラコ梅干しおにぎりの具
02020/9/1001梅干し
12020/10/1100サケ
22020/11/1010タラコ
32020/12/1010タラコ
42021/1/1001梅干し

ちなみに質問コードのエラーの原因ですが、onigiri_map() は返り値がないため、

s.map(onigiri_map())

s.map(None)

とやっているのと一緒なので、エラーになります。

投稿2021/01/31 03:08

編集2021/01/31 03:13
tiitoi

総合スコア21956

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

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

gogotowel

2021/01/31 04:14

約15秒が約1.5秒に縮まりました。すごい効果です。 大変ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問