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

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

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

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

pandas

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

Q&A

解決済

2回答

853閲覧

lamda式を使って、dfのcolumnsを編集する方法

MagMag

総合スコア80

Python 3.x

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

pandas

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

0グッド

0クリップ

投稿2020/03/31 09:12

実現したいこと

Pandasのメソッドチェーンを用いてDataFrameを処理しているのですが、途中で列名を変更するチェーン処理方法わからないです。対応方法があればご教示願います。

エラーに出ている通り、lambdaでは代入ができないとのことなのですが、メソッドチェーンで対応する方法はありますでしょうか?

lamda式を使わない方法

Python

1import pandas as pd 2df = pd.DataFrame(np.arange(10).reshape(5,2), columns=['A', 'B']) 3df.columns = pd.MultiIndex.from_product([['C'], df.columns]) 4 5# C 6# A B 7#0 0 1 8#1 2 3 9#2 4 5 10#3 6 7 11#4 8 9 12

試したこと

df.pipe(lambda df: df.columns= pd.MultiIndex.from_product([['C'], df.columns])) #SyntaxError: lambda cannot contain assignment

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

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

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

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

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

guest

回答2

0

pandas.DataFrame.set_axis — pandas 1.0.3 documentation

python

1df = (pd.DataFrame(np.arange(10).reshape(5,2), columns=['A', 'B']) 2 .pipe(lambda df: df.set_axis(pd.MultiIndex.from_product([['C'], df.columns]), axis='columns'))) 3 4df 5# C 6# A B 7# 0 0 1 8# 1 2 3 9# 2 4 5 10# 3 6 7 11# 4 8 9

質問の例の場合は、

python

1df = pd.concat({'C': pd.DataFrame(np.arange(10).reshape(5,2), columns=['A', 'B'])}, axis=1) 2 3df 4# C 5# A B 6# 0 0 1 7# 1 2 3 8# 2 4 5 9# 3 6 7 10# 4 8 9

でも可能ですが……。

投稿2020/03/31 14:51

kirara0048

総合スコア1399

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

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

MagMag

2020/04/01 09:21 編集

ありがとうございます。私の力だと後から読めないので、素直にdefで組むようにします。
guest

0

ベストアンサー

lambda式内で代入する方法、出来なくはないですが、
コードが無駄に読みにくくなるのでお勧めしません。

import numpy as np import pandas as pd df = pd.DataFrame(np.arange(10).reshape(5,2), columns=['A', 'B']) df = df.pipe(lambda df:(df, setattr(df, "columns", pd.MultiIndex.from_product([['C'], df.columns])))[0])

lambda の部分

python

1lambda df: (df, setattr(df, "column", ...))[0]

pipe()が値を返さないといけないので、
辻褄を合わせる為のコードが必要になります
(df, ...)[0] -> df を返す

また、これはオブジェクトでの例ですが、
辞書への代入の場合等はまた別の方法になったりするので、
無理に lambda でやろうとせずに、関数へ切り出した方がよいです。


python 3.8 で導入された 代入 では出来るのかなと、
一応、調べましたが、期待する使い方は出来なさそう。

PEP 572 -- Assignment Expressions

Unparenthesized assignment expressions are prohibited in lambda functions. Example: (lambda: x := 1) # INVALID lambda: (x := 1) # Valid, but unlikely to be useful (x := lambda: 1) # Valid lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid

投稿2020/03/31 11:08

teamikl

総合スコア8760

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

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

MagMag

2020/03/31 12:47

ありがとうございました。 ちなみにlambdaではなく関数を定義してメソッドチェーンを作る場合、どのメソッドを使用したらいいでしょうか?def col_convert(df)を作って、df.pipe(col_converter)としてはみたのですが、関数に別の引数を入れたいので、うまくいきませんでした。
teamikl

2020/03/31 13:25

どのような引数を想定してますか? 他の引数を渡すには、 def col_convert(df, arg1, arg2): ... として df.pipe(col_convert, arg1, arg2)
MagMag

2020/04/01 00:37 編集

今回の例は2階層のmultiindex化ですが、階数を引数にして、場合によっては3階層にしたいと思っています。その意味では、教えていただいた処理でいけそうでうね。やってみます!
MagMag

2020/04/01 00:17 編集

以下関数を組んで、df.pipe(set_muti_cols, n_level=2)で動作しました。ドキュメンテーションをきちんと確認しておらず、申し訳ありません。 def set_multi_cols(df, n_level=2):   if n_level ==2:    df.columns = pd.MultiIndex.from_product([['C'], df.columns])   elif n_level ==3:    df.columns = pd.MultiIndex.from_product([['D'], ['C'], df.columns])   return df ただ、この操作をしたところ、dfの中身も変わってしまうようでした(参照ではなく代入操作になっている)。本筋と違うのですが、pipe(lambda df: )だと参照なのに、関数を定義して呼び出すとなぜ代入になるのでしょうか?
teamikl

2020/04/01 02:44

dfA = df.pipe(lambda df: ...) # 元の df は変化しない dfB = df.pipe( `df.columns = `使った関数 ) # 元の dfが変化 という事だと思いますが、代入の様な副作用を伴う操作の為です。 lambda <=> 関数だからというわけではなく、代入などが無ければ関数でも大丈夫。 (必要なら事前に df.copy()、メソッドチェーンで使う専用の関数も内部でcopy()しています)
MagMag

2020/04/01 09:17

なるほど。defの中でdf.copy()で新しい変数を作って対応したら、実装できました。ありがとうございました。色々と教えていただいたのでベストアンサーにさせてください!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問