1. ホーム
  2. python

[解決済み] パンダの.atと.locの比較

2022-03-08 22:33:48

質問

コードを最適化する方法を探っていたら pandas .at というメソッドがあります。にあたります。 ドキュメント

ラベルベースの高速スカラアクセサ

locと同様に、atでもラベルベースのスカラー検索が可能である。また、これらのインデクサを使用して設定することもできる。

そこで、いくつかのサンプルを実行してみました。

セットアップ

import pandas as pd
import numpy as np
from string import letters, lowercase, uppercase

lt = list(letters)
lc = list(lowercase)
uc = list(uppercase)

def gdf(rows, cols, seed=None):
    """rows and cols are what you'd pass
    to pd.MultiIndex.from_product()"""
    gmi = pd.MultiIndex.from_product
    df = pd.DataFrame(index=gmi(rows), columns=gmi(cols))
    np.random.seed(seed)
    df.iloc[:, :] = np.random.rand(*df.shape)
    return df

seed = [3, 1415]
df = gdf([lc, uc], [lc, uc], seed)

print df.head().T.head().T

df のように見える。

            a                                        
            A         B         C         D         E
a A  0.444939  0.407554  0.460148  0.465239  0.462691
  B  0.032746  0.485650  0.503892  0.351520  0.061569
  C  0.777350  0.047677  0.250667  0.602878  0.570528
  D  0.927783  0.653868  0.381103  0.959544  0.033253
  E  0.191985  0.304597  0.195106  0.370921  0.631576

を使用しましょう。 .at.loc そして、同じものを得ることを確認します。

print "using .loc", df.loc[('a', 'A'), ('c', 'C')]
print "using .at ", df.at[('a', 'A'), ('c', 'C')]

using .loc 0.37374090276
using .at  0.37374090276

を使用して速度をテストします。 .loc

%%timeit
df.loc[('a', 'A'), ('c', 'C')]

10000 loops, best of 3: 180 µs per loop

を使用して速度をテストします。 .at

%%timeit
df.at[('a', 'A'), ('c', 'C')]

The slowest run took 6.11 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 8 µs per loop

これは大幅なスピードアップになりそうですね。 キャッシュの段階でも 6.11 * 8 よりもはるかに高速です。 180

質問

の制限とは何ですか? .at ? 使ってみたいという気持ちがあります。 ドキュメントによると、これは .loc が、似たような挙動をしない。 例を挙げます。

# small df
sdf = gdf([lc[:2]], [uc[:2]], seed)

print sdf.loc[:, :]

          A         B
a  0.444939  0.407554
b  0.460148  0.465239

ここで print sdf.at[:, :] の結果は TypeError: unhashable type

だから、たとえ似ていることを意図していても明らかに同じではない。

とはいえ、何ができて何ができないのか、誰がガイダンスしてくれるのでしょうか。 .at メソッドを使用することができますか?

どのように解決するのですか?

更新してください。 df.get_value はバージョン 0.21.0 で非推奨となりました。使用方法 df.at または df.iat を推奨しています。


df.at は一度に1つの値しかアクセスできません。

df.loc は、複数の行や列を選択することができます。

また df.get_value これは、単一の値へのアクセスをより迅速に行うことができる。

In [25]: %timeit df.loc[('a', 'A'), ('c', 'C')]
10000 loops, best of 3: 187 µs per loop

In [26]: %timeit df.at[('a', 'A'), ('c', 'C')]
100000 loops, best of 3: 8.33 µs per loop

In [35]: %timeit df.get_value(('a', 'A'), ('c', 'C'))
100000 loops, best of 3: 3.62 µs per loop


ボンネットの中 df.at[...] コール df.get_value を行うが、同時に タイプチェック のキーになります。