.apply
はではありません。は、軸上の反復よりも一般的に高速です。私はフードの下では、このケースでは毎回関数呼び出しのオーバヘッドが発生することを除いて、軸上のループに過ぎないと考えています。
source codeを見ると、指示された軸を反復して関数を適用し、個々の結果を一連の辞書として構築し、最終的にaを返す辞書のデータフレームコンストラクタを呼び出していることがわかります新しいデータフレーム:具体的に
if axis == 0:
series_gen = (self._ixs(i, axis=1)
for i in range(len(self.columns)))
res_index = self.columns
res_columns = self.index
elif axis == 1:
res_index = self.index
res_columns = self.columns
values = self.values
series_gen = (Series.from_array(arr, index=res_columns, name=name,
dtype=dtype)
for i, (arr, name) in enumerate(zip(values,
res_index)))
else: # pragma : no cover
raise AssertionError('Axis must be 0 or 1, got %s' % str(axis))
i = None
keys = []
results = {}
if ignore_failures:
successes = []
for i, v in enumerate(series_gen):
try:
results[i] = func(v)
keys.append(v.name)
successes.append(i)
except Exception:
pass
# so will work with MultiIndex
if len(successes) < len(res_index):
res_index = res_index.take(successes)
else:
try:
for i, v in enumerate(series_gen):
results[i] = func(v)
keys.append(v.name)
except Exception as e:
if hasattr(e, 'args'):
# make sure i is defined
if i is not None:
k = res_index[i]
e.args = e.args + ('occurred at index %s' %
pprint_thing(k),)
raise
if len(results) > 0 and is_sequence(results[0]):
if not isinstance(results[0], Series):
index = res_columns
else:
index = None
result = self._constructor(data=results, index=index)
result.columns = res_index
if axis == 1:
result = result.T
result = result._convert(datetime=True, timedelta=True, copy=False)
else:
result = Series(results)
result.index = res_index
return result
:
series_gen
が要求された軸に基づいて構築された
for i, v in enumerate(series_gen):
results[i] = func(v)
keys.append(v.name)
。
機能のパフォーマンスを向上させるには、hereのアドバイスに従ってください。
基本的に、あなたのオプションは次のとおりです。
- は、大規模なデータフレームの外へ
をパフォーマンスを圧迫する使用
numba
(JITコンパイラ)pandas.eval