質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

10219閲覧

pandas DataFrame における indexでの参照について

ultraman

総合スコア12

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2017/07/22 15:15

###原因と対策、アドバイスをお願いします。

下記の手順において
DataFrameの作成の際にnumpy.datetime64でdate列を作成すると
NaTがあるrowはpandas._libs.tslib.Timestampに変換されてしまうため
indexの参照時にKeyErrorが発生してしまう。

なぜ NaTがあるrowがpandas._libs.tslib.Timestampnに変換されるのでしょうか?
変換されないようにするにはどうしたらよろしいでしょうか?
または、indexに複数の型が混在する下記の状況でもnp.datetime64で参照できる方法はありますか?

よろしくお願いします。

###発生している問題・エラーメッセージ

python

1KeyError: numpy.datetime64('2017-07-19T14:24:07.000000000')

###該当のソースコード

データ作成

python

1import numpy as np 2import pandas as pd 3 4dates = [ 5 np.datetime64('2014-11-09 10:00:00.000000000') 6 , np.datetime64('2015-11-09 10:00:00.000000000') 7 , np.datetime64('2016-11-09 10:00:00.000000000') 8 , np.datetime64('2017-07-19 14:24:07.000000000') 9] 10 11prices = [ 12 2000 13 , 1900 14 , 1800 15] 16 17df = pd.DataFrame([dates, prices], ['date', 'price']).T 18

date price
0 2014-11-09T10:00:00.000000000 2000
1 2015-11-09T10:00:00.000000000 1900
2 2016-11-09T10:00:00.000000000 1800
3 2017-07-19 14:24:07 NaT

python

1type(df.date[0]) #出力 numpy.datetime64 2type(df.date[3]) #出力 pandas._libs.tslib.Timestamp

date列をindexに設定

python

1df = df.set_index('date')

date
2014-11-09T10:00:00.000000000 2000
2015-11-09T10:00:00.000000000 1900
2016-11-09T10:00:00.000000000 1800
2017-07-19 14:24:07 NaT

indexで参照

python

1df.ix[dates[0]] #出力 price 2000 2 # Name: 2014-11-09T10:00:00.000000000, dtype: object 3 4df.ix[dates[1]] #出力 KeyError: numpy.datetime64('2017-07-19T14:24:07.000000000')

###補足情報(言語/FW/ツール等のバージョンなど)
python: 3.5.3
pandas: 0.20.1
anaconda: 3-2.4.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

たぶんこのように記述すると大丈夫かと思います。

Python

1import pandas as pd 2import numpy as np 3 4dates = [ 5 np.datetime64('2014-11-09 10:00:00.000000000'), 6 np.datetime64('2015-11-09 10:00:00.000000000'), 7 np.datetime64('2016-11-09 10:00:00.000000000'), 8 np.datetime64('2017-07-19 14:24:07.000000000') 9] 10 11prices = [2000,1900,1800] 12 13df = pd.DataFrame({'date':pd.Series(dates), 'price':pd.Series(prices)}) 14df = df.set_index("date") 15print(df)

【補足】

質問のように、4行目のみ型が違う原因は、DataFrame 作成の際に
一度

Python

1df = pd.DataFrame([dates, prices], ['date', 'price'])

とした後に、Tで転置してためかと思います。

Pandas では列毎にが決まるため、上記のように記述すると、
datetime64型のデータとint64型のデータが同じ列にいる為に、型がobject型に変換されてしまいます。ところが4行目(この時点では4列目)だけはint64型のデータが存在しない為、この行だけdatetime64型のままでデータが保存されることとなります。

投稿2017/07/22 15:51

編集2017/07/22 16:10
magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ultraman

2017/07/22 16:02 編集

ご回答ありがとうございます。 せっかくご回答いただいたのですが、 最初のdf作成は pd.io.sql.read_sql()  によりDBより読み込み作成しています。 (再現しやすいようにコードでの作成として質問しました。) このため、アドバイスいただいたように df = pd.DataFrame({'date':pd.Series(dates), 'price':pd.Series(prices)}) とすることができません。 DBで読み込んだ際にNaTがあるrowに対して型が変換されてしまっています。
magichan

2017/07/22 16:05

とりあえず、このような現象になる原因を補足として追記しました。
magichan

2017/07/22 16:08

sqlからの取り込みはあまり経験がないのですが、結局 datetime型をdatetime型のまま、列データに取り込むことが出来れば、問題は起こらないということです。
magichan

2017/07/22 16:21

すみません。難しく考えてました。 set_index() 実行の前に df['date'] = df['date'].astype(np.datetime64) で型変換してあげると問題が解決するかもしれません。
ultraman

2017/07/22 17:04

いろいろ情報ありがとうございます。 教えていただいた補足をヒントに何とか解決できました。 しかも、astypeで変換する方法もありましたね。 とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問