2列のパンダデータフレームがあります。最初の列の値を2番目の列に影響を与えずに変更し、最初の列の値だけを変更してデータフレーム全体を元に戻す必要があります。パンダでapplyを使ってそれをどのようにすることができますか?
サンプルデータフレームをdf
とします。
a,b
1,2
2,3
3,4
4,5
あなたが欲しいのは:
df['a'] = df['a'].apply(lambda x: x + 1)
それは戻ります:
a b
0 2 2
1 3 3
2 4 4
3 5 5
あなたはまったく関数を必要としません。列全体を直接操作できます。
データ例:
>>> df = pd.DataFrame({'a': [100, 1000], 'b': [200, 2000], 'c': [300, 3000]})
>>> df
a b c
0 100 200 300
1 1000 2000 3000
a
列のすべての値を半分にします。
>>> df.a = df.a / 2
>>> df
a b c
0 50 200 300
1 500 2000 3000
次のようにmap()
を使ったほうがよい単一の列の場合:
df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])
a b c
0 15 15 5
1 20 10 7
2 25 30 9
df['a'] = df['a'].map(lambda a: a / 2.)
a b c
0 7.5 15 5
1 10.0 10 7
2 12.5 30 9
与えられた応答は正しいですが、初期データフレームを変更しますが、これは常に望ましいとは限りません(そして、OPが例「apply
を使用する」を求められた場合、apply
が行うように、新しいデータフレームを返すバージョンが必要かもしれません)。
これは assign
を使用して可能です。ドキュメントの状態(強調は私のものです)として、既存の列に対してassign
が有効です。
新しい列をDataFrameに割り当てます。
新しいオブジェクトと、新しい列に加えてすべての元の列を返します。 再割り当てされた既存の列は上書きされます。
要するに:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])
In [3]: df.assign(a=lambda df: df.a / 2)
Out[3]:
a b c
0 7.5 15 5
1 10.0 10 7
2 12.5 30 9
In [4]: df
Out[4]:
a b c
0 15 15 5
1 20 10 7
2 25 30 9
関数には、変更する列だけでなく、データフレーム全体が渡されることに注意してください。そのため、ラムダで正しい列を選択していることを確認する必要があります。
適用関数の実行速度に本当に関心があり、作業する巨大なデータセットがある場合は、swifterを使用して実行を高速化できます。pandasデータフレームのswifterの例を次に示します。
import pandas as pd
import swifter
def fnc(m):
return m*3+4
df = pd.DataFrame({"m": [1,2,3,4,5,6], "c": [1,1,1,1,1,1], "x":[5,3,6,2,6,1]})
# apply a self created function to a single column in pandas
df["y"] = df.m.swifter.apply(fnc)
これにより、すべてのCPUコアで結果を計算できるため、通常の適用機能よりもはるかに高速になります。それがあなたにとって有用になるかどうか私に知らせてください。