2015-12-25 3 views
6

誰かがこの動作を私に説明できますか?リストとのインデックス付き.ixインデックスの使用による予期しない結果

import pandas as pd 

dates = pd.date_range('1/1/2000', periods=8) 
df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) 

df.ix['2000-01-01':'2000-01-02', ['A', 'C']] 

## Output: 
        A   C 
2000-01-01 0.224944 -0.689382 
2000-01-02 -0.824735 -0.805512 

df.ix[['2000-01-01', '2000-01-02'], ['A', 'C']] 

## Output: 
      A C 
2000-01-01 NaN NaN 
2000-01-02 NaN NaN 

私は両方のインデックス作成操作が同じ(最初の)結果を返すことを期待していました。私はパンダの内部を知らない、今

from datetime import datetime 

df.loc[[datetime(2000, 1, 1), datetime(2000, 1, 5)], ['A','C']] 

## Output 
        A   C 
2000-01-01 0.224944 -0.689382 
2000-01-05 -0.393747 0.462126 

、それは暗黙的に日付の文字列を変換し、なぜ範囲を与えられたときには、リストを与えられていないとき、私:

は、その後、私は一種のそれを得ました推測では、序数的な性質を持つオブジェクトを意味しているので、パンダはおそらくインデックスをチェックし、それが日時であると見て、その文字列を日付として解析します。

しかし、問題は、なぜ私たちが単一の文字列を供給するときに正しいことをするのでしょうか?

df.loc['2000-01-01', ['A','C']] 

## Output: 
A 0.224944 
C -0.689382 
Name: 2000-01-01 00:00:00, dtype: float64 

リストが与えられたときに複数の値を変換しようとしないのはパフォーマンス上の問題ですか?いくつかの他のデザインの決定?

+1

予期せぬ挙動を解明するのがさらに簡単です: 'df.ix [['2000-01-01'、 '2000-01-02']]' - NaNを与える – shx2

+1

@ shx2まさに。そしてあなたが指摘したように、それは1つの日付文字列で正しいことを行います。 – kliron

+0

私はこれが既知のバグだとはかなり確信していますが、誰もそれを実装したくない(または少なくとも誰も持っていません)。編集:私はgithubでそれを見つけることができません...しかし、それはどこかにあると思う。 –

答えて

1

文字列を使ってDatetimeIndexにアクセスすると、なんらかのハッキングが発生します(これはRがそこにあるため、このようなエッジケースを見つけるのは簡単です)。すなわち、

  • スライスのために働きます。
  • シングルアクセスで動作します。
  • 一部の場合はになる可能性がありますが、それ以上はカウントしません。

文字列ではなく、タイムスタンプを使用することがはるかに良いです。(この場合、曖昧さのないけれども)

In [11]: df.ix[pd.Timestamp('2000-01-01'), ['A','C']] 
Out[11]: 
A 0.480959 
C 0.468689 
Name: 2000-01-01 00:00:00, dtype: float64 

In [12]: df.ix[pd.Timestamp('2000-01-01'):pd.Timestamp('2000-01-02'), ['A','C']] 
Out[12]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

In [13]: df.ix[[pd.Timestamp('2000-01-01'), pd.Timestamp('2000-01-02')], ['A', 'C']] 
Out[13]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

In [14]: df.ix[pd.to_datetime(['2000-01-01', '2000-01-02']), ['A', 'C']] 
Out[14]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

あなたの答えで述べたように、これは少しクリーナーではなく.locとして.ixより。

関連する問題