基本的な例でこれらのベクトル化法を使用する時期を教えてください。
map
はSeries
メソッドで、残りはDataFrame
メソッドです。私はapply
とapplymap
メソッドについて混乱しました。関数をDataFrameに適用する方法が2つあるのはなぜですか?繰り返しますが、使い方を説明する簡単な例は素晴らしいでしょう。
Wes McKinneyの Python for Data Analysisからのストレート book、pg。 132(私はこの本を強く薦める):
もう1つのよくある操作は、1D配列の関数を各列または行に適用することです。 DataFrameのapplyメソッドはまさにこれを行います。
In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [117]: frame
Out[117]:
b d e
Utah -0.029638 1.081563 1.280300
Ohio 0.647747 0.831136 -1.549481
Texas 0.513416 -0.884417 0.195343
Oregon -0.485454 -0.477388 -0.309548
In [118]: f = lambda x: x.max() - x.min()
In [119]: frame.apply(f)
Out[119]:
b 1.133201
d 1.965980
e 2.829781
dtype: float64
最も一般的な配列統計(sumやmeanなど)の多くはDataFrameメソッドなので、applyを使用する必要はありません。
要素別のPython関数も使用できます。フレーム内の各浮動小数点値からフォーマットされた文字列を計算したいとします。これをapplymapで行うことができます。
In [120]: format = lambda x: '%.2f' % x
In [121]: frame.applymap(format)
Out[121]:
b d e
Utah -0.03 1.08 1.28
Ohio 0.65 0.83 -1.55
Texas 0.51 -0.88 0.20
Oregon -0.49 -0.48 -0.31
Applymapという名前の理由は、Seriesには要素ごとの関数を適用するためのmapメソッドがあるためです。
In [122]: frame['e'].map(format)
Out[122]:
Utah 1.28
Ohio -1.55
Texas 0.20
Oregon -0.31
Name: e, dtype: object
まとめると、apply
はDataFrameの行/列ベースで機能し、applymap
はDataFrameの要素単位で機能し、map
はシリーズの要素単位で機能します。
これらの答えにはすばらしい情報がありますが、どのメソッドが配列ワイズと要素ワイズのどちらで機能するかを明確に要約するために私自身を追加します。 jeremiahbuddhaはほとんどこれをしましたが、Series.applyについては言及しませんでした。コメントする担当者がいません。
DataFrame.apply
は一度に行全体または列全体に作用します。
DataFrame.applymap
、Series.apply
、およびSeries.map
は一度に1つの要素を操作します。
Series.apply
とSeries.map
の機能には多くの重複があります。つまり、どちらの機能もほとんどの場合に機能します。ただし、若干の違いはありますが、そのいくつかはosaの回答で説明されています。
他の答えに加えて、Series
name__には map と apply もあります。
ApplyはDataFrameをシリーズから作成することができます ;しかし、mapは他のシリーズのすべてのセルにシリーズを配置するだけです。おそらくこれはあなたが望むものではありません。
In [40]: p=pd.Series([1,2,3])
In [41]: p
Out[31]:
0 1
1 2
2 3
dtype: int64
In [42]: p.apply(lambda x: pd.Series([x, x]))
Out[42]:
0 1
0 1 1
1 2 2
2 3 3
In [43]: p.map(lambda x: pd.Series([x, x]))
Out[43]:
0 0 1
1 1
dtype: int64
1 0 2
1 2
dtype: int64
2 0 3
1 3
dtype: int64
dtype: object
また、「Webサーバーへの接続」などの副作用のある機能を使用している場合は、わかりやすくするためにapply
name__を使用します。
series.apply(download_file_for_every_element)
Map
name__は、関数だけでなく、辞書または他のシリーズも使用できます。 あなたが 順列を操作したいとしましょう 。
取る
1 2 3 4 5
2 1 4 5 3
この順列の二乗は、
1 2 3 4 5
1 2 5 3 4
map
name__を使って計算できます。セルフアプリケーションが文書化されているかどうかはわかりませんが、0.15.1
で機能します。
In [39]: p=pd.Series([1,0,3,4,2])
In [40]: p.map(p)
Out[40]:
0 0
1 1
2 4
3 2
4 3
dtype: int64
@jeremiahbuddhaは、applyは行/列に作用し、applymapは要素ごとに作用すると述べました。しかし、それはあなたがまだ要素ごとの計算にapplyを使うことができるようです....
frame.apply(np.sqrt)
Out[102]:
b d e
Utah NaN 1.435159 NaN
Ohio 1.098164 0.510594 0.729748
Texas NaN 0.456436 0.697337
Oregon 0.359079 NaN NaN
frame.applymap(np.sqrt)
Out[103]:
b d e
Utah NaN 1.435159 NaN
Ohio 1.098164 0.510594 0.729748
Texas NaN 0.456436 0.697337
Oregon 0.359079 NaN NaN
ちょっと指摘したかったのですが、少し苦労しました。
def f(x):
if x < 0:
x = 0
Elif x > 100000:
x = 100000
return x
df.applymap(f)
df.describe()
df = df.applymap(f)
df.describe()
たぶん最も簡単な説明はapplyとapplymapの違いです:
apply 列全体をパラメータとして使用し、結果をこの列に割り当てます。
applymap は別のセル値をパラメータとして取り、結果をこのセルに割り当てます。
注意applyが単一の値を返す場合は、代入後に列ではなくこの値を使用し、最終的には行列ではなく行のみを使用します。
私の理解:
機能の観点からは:
関数に列/行内で比較する必要がある変数がある場合は、apply
を使用します。
例:lambda x: x.max()-x.mean()
.
関数が各要素に適用される場合:
1>列/行が見つかった場合はapply
を使用
2>データフレーム全体に適用する場合はapplymap
を使用してください。
majority = lambda x : x > 17
df2['legal_drinker'] = df2['age'].apply(majority)
def times10(x):
if type(x) is int:
x *= 10
return x
df2.applymap(times10)
map
、 applymap
、および ap
ply
:の比較最初の主な違い: _ definition _
map
はシリーズのみで定義されていますapplymap
はDataFramesでのみ定義されていますapply
はBOTHで定義されています第二の主な違い: 入力引数
map
はdict
s、Series
、またはcallableを受け入れますapplymap
とapply
は呼び出し可能オブジェクトのみを受け入れます3番目の大きな違い: _動作_
map
はSeriesの場合はelementwiseですapplymap
はDataFrameの場合はelementwiseです。apply
も要素ごとに機能しますが、より複雑な操作や集計に適しています。動作と戻り値は関数によって異なります。4番目の大きな違い(最も重要なもの): ユースケース
map
はあるドメインから別のドメインへ値をマッピングするためのもので、パフォーマンスのために最適化されています。applymap
は複数の行/列にわたる要素ごとの変換に適していますapply
はベクトル化できない関数を適用するためのものです脚注
map
は辞書/シリーズに渡されると、その辞書/シリーズのキーに基づいて要素をマップします。欠落している値は、出力にNaNとして記録されます。最近のバージョンの
applymap
はいくつかの操作に最適化されています。場合によっては、applymap
がapply
よりわずかに速いことがわかります。私の提案は、それらを両方ともテストして、うまくいくものなら何でも使うことです。
map
は要素単位のマッピングと変換に最適化されています。辞書またはシリーズを含む操作は、パンダがより良いパフォーマンスのためにより速いコードパスを使うことを可能にします。Series.apply
は集約演算のスカラを返し、そうでなければSeriesを返します。DataFrame.apply
についても同様です。apply
、mean
などの特定のNumPy関数で呼び出された場合、sum
もファストパスを持ちます。
FOMO:
次の例は、 apply
および applymap
をDataFrame
に適用したものです。
map
functionはSeriesにのみ適用できます。 DataFrameに map
を適用することはできません。
覚えておくべきことは、 apply
は 何でもできる applymap
ができますが、 apply
は eXtra オプションを持っているということです。
Xファクターのオプションは次のとおりです。axis
およびresult_type
ここで、result_type
は、axis=1
(列用)の場合にのみ機能します。
df = DataFrame(1, columns=list('abc'),
index=list('1234'))
print(df)
f = lambda x: np.log(x)
print(df.applymap(f)) # apply to the whole dataframe
print(np.log(df)) # applied to the whole dataframe
print(df.applymap(np.sum)) # reducing can be applied for rows only
# apply can take different options (vs. applymap cannot)
print(df.apply(f)) # same as applymap
print(df.apply(sum, axis=1)) # reducing example
print(df.apply(np.log, axis=1)) # cannot reduce
print(df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')) # expand result