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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

1172閲覧

pandasの時間条件で該当する条件の一番最初の値を取得したい

aws

総合スコア48

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2020/11/03 19:06

pandasの時間条件で該当する条件の一番最初の値(int)を取得したいと考えているのですがどの様にすると良いでしょうか?

データサンプル

indextimeint
02020.05.01 02:0015
12020.05.01 02:0314
22020.05.01 02:1119
32020.05.01 02:1615
42020.05.01 02:1814
52020.05.01 02:2312
62020.05.01 02:2618
72020.05.01 02:2911
82020.05.01 02:3013
92020.05.01 02:3316
102020.05.01 02:3711
112020.05.01 02:4419
122020.05.01 03:4517

上記データにて index 0 の time 2020.05.01 02:00 の25分後の最初の値を取得する場合。
正解は index 6, time 2020.05.01 02:26, int 18になります。

上記データにて index 2 の time 2020.05.01 02:03 の25分後の最初の値を取得する場合。
正解は index 7, time 2020.05.01 02:29, int 11になります。

上記データにて index 3 の time 2020.05.01 02:11 の25分後の最初の値を取得する場合。
正解は index 10, time 2020.05.01 02:37, int 11になります。

○○分後(今回は25分)は一定です。
timeは一定ではないのでデータをズラして値を取得する事は出来ません。

理想の結果
|index |time |int |int_25M|
|:--|:--:|--:|
|0 |2020.05.01 02:00 |15 | 18|
|1 |2020.05.01 02:03 |14 | 11|
|2 |2020.05.01 02:11 |19 | 11|
|3 |2020.05.01 02:16 |15 | 19|
|4 |2020.05.01 02:18 |14 | 19|
|5 |2020.05.01 02:23 |12 | NaN|
|6 |2020.05.01 02:26 |18 | NaN|
|7 |2020.05.01 02:29 |11 | NaN|
|8 |2020.05.01 02:30 |13 | NaN|
|9 |2020.05.01 02:33 |16 | NaN|
|10 |2020.05.01 02:37 |11 | NaN|
|11 |2020.05.01 02:44 |19 | NaN|
|12 |2020.05.01 03:45 |17 | NaN|

こんな感じのデータを出力したいと考えています。

プログラム書いては見ましたが。。。

最初読み込んだデータを二つにして一行ずつ比較すればいいのかと考えてみました。
※まずはindexが取得出来るかどうかの確認してみました。

df_1 = pd.read_csv("hogehoge.csv") df_1['time'] = pd.to_datetime(df_1['time']) df_2 = df_1 df_2['data_25m'] = df_2['time'] + dt.timedelta(minutes=25) for idx,row in df_2.iterrows(): try: df_1['int_25M'] = df_1[df_1['time'] > row['data_25m']].index[0] except: print("ありません")

結果
|index |time |int |int_25M|
|:--|:--:|--:|
|0 |2020.05.01 02:00 |15 | 12|
|1 |2020.05.01 02:03 |14 | 12|
|2 |2020.05.01 02:11 |19 | 12|
|3 |2020.05.01 02:16 |15 | 12|
|4 |2020.05.01 02:18 |14 | 12|
|5 |2020.05.01 02:23 |12 | 12|
|6 |2020.05.01 02:26 |18 | 12|
|7 |2020.05.01 02:29 |11 | 12|
|8 |2020.05.01 02:30 |13 | 12|
|9 |2020.05.01 02:33 |16 | 12|
|10 |2020.05.01 02:37 |11 | 12|
|11 |2020.05.01 02:44 |19 | 12|
|12 |2020.05.01 03:45 |17 | 12|

うまくいきませんでした。

どの様にプログラムを書くと良いでしょうか?
宜しくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

時刻列がソートされているならば、pd.Series.searchsorted()を使いましょう。

python

1import io 2 3import numpy as np 4import pandas as pd 5 6data = """index,time,int 70,2020-05-01 02:00:00,15 81,2020-05-01 02:03:00,14 92,2020-05-01 02:11:00,19 103,2020-05-01 02:16:00,15 114,2020-05-01 02:18:00,14 125,2020-05-01 02:23:00,12 136,2020-05-01 02:26:00,18 147,2020-05-01 02:29:00,11 158,2020-05-01 02:30:00,13 169,2020-05-01 02:33:00,16 1710,2020-05-01 02:37:00,11 1811,2020-05-01 02:44:00,19 1912,2020-05-01 02:45:00,17""" 20df = pd.read_csv(io.StringIO(data), parse_dates=['time']) 21 22 23int_array = np.r_[df['int'].to_numpy(), np.nan] # int列の最後にnanを継ぎ足した配列 24time_25m = df['time'] + pd.Timedelta('25m') # time列の25分後 25out = int_array[df['time'].searchsorted(time_25m)] 26print(out) 27# [18. 11. 11. 19. 19. nan nan nan nan nan nan nan nan] 28 29print(df.assign(int_25M=out)) 30# index time int int_25M 31# 0 0 2020-05-01 02:00:00 15 18.0 32# 1 1 2020-05-01 02:03:00 14 11.0 33# 2 2 2020-05-01 02:11:00 19 11.0 34# 3 3 2020-05-01 02:16:00 15 19.0 35# 4 4 2020-05-01 02:18:00 14 19.0 36# 5 5 2020-05-01 02:23:00 12 NaN 37# 6 6 2020-05-01 02:26:00 18 NaN 38# 7 7 2020-05-01 02:29:00 11 NaN 39# 8 8 2020-05-01 02:30:00 13 NaN 40# 9 9 2020-05-01 02:33:00 16 NaN 41# 10 10 2020-05-01 02:37:00 11 NaN 42# 11 11 2020-05-01 02:44:00 19 NaN 43# 12 12 2020-05-01 02:45:00 17 NaN

Series.searchsorted(値)を実行すると、値がソート済みシリーズの何番目に挿入されるかがわかります。
例えば上の例で値が02:25:00ならば、これは5番目の02:23:00と6番目の02:26:00の間に挿入されるので、6が返ってきます。値を配列にすれば、そのそれぞれが何番目に挿入されるかがわかります。

int列をsearchsortedの結果で引っ張ってくれば求める配列になります。
ただしここで、02:48:00を挿入する場合はsearchsortedの結果13が返ってきますが、int列に13番目はなく、またこの行は最終的な結果を「NaN」にしたいので、int列の最後(13番目)にnp.nanを加えた配列int_arrayを作成しています。

投稿2020/11/04 01:21

kirara0048

総合スコア1399

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

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

aws

2020/11/04 06:58

ご回答ありがとうございます。 searchsortedを初めて利用しましたが素晴らしいです。 また実行速度も速いので感動です。 またCSV読み込み時の"parse_dates=['time']"も勉強になりました。 本当にありがとうございます。
guest

0

処理のところを変えてみました。
1行ずつ回していって、df_tという「その行のdata_25mより大きなtimeをもつ行だけ残したdataframe」です。それが空でなければ、先頭の行のintをdf_2のint_25mに入れています。
ところで、貼られたデータの最終行は12 2020.05.01 03:45 17となっていますが、正しい時刻は02:45で合っていますか。これだと後半の行はすべてint_25mが17になってしまいます。

python3

1import datetime as dt 2import pandas as pd 3 4df_1 = pd.read_csv("hogehoge.csv") 5df_1['time'] = pd.to_datetime(df_1['time']) 6df_2 = df_1 7df_2['data_25m'] = df_2['time'] + dt.timedelta(minutes=25) 8df_2['int_25m'] = "" 9for i in df_2.index: 10 df_t = df_2[df_2['time'] > df_2.at[i,'data_25m']] 11 if len(df_t): 12 df_2.at[i,'int_25m'] = df_t.iloc[0,2] 13 14print(df_2) 15# index time int data_25m int_25m 16# 0 0 2020-05-01 02:00:00 15 2020-05-01 02:25:00 18 17# 1 1 2020-05-01 02:03:00 14 2020-05-01 02:28:00 11 18# 2 2 2020-05-01 02:11:00 19 2020-05-01 02:36:00 11 19# 3 3 2020-05-01 02:16:00 15 2020-05-01 02:41:00 19 20# 4 4 2020-05-01 02:18:00 14 2020-05-01 02:43:00 19 21# 5 5 2020-05-01 02:23:00 12 2020-05-01 02:48:00 22# 6 6 2020-05-01 02:26:00 18 2020-05-01 02:51:00 23# 7 7 2020-05-01 02:29:00 11 2020-05-01 02:54:00 24# 8 8 2020-05-01 02:30:00 13 2020-05-01 02:55:00 25# 9 9 2020-05-01 02:33:00 16 2020-05-01 02:58:00 26# 10 10 2020-05-01 02:37:00 11 2020-05-01 03:02:00 27# 11 11 2020-05-01 02:44:00 19 2020-05-01 03:09:00 28# 12 12 2020-05-01 02:45:00 17 2020-05-01 03:10:00

投稿2020/11/03 23:08

jeanbiego

総合スコア3966

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

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

aws

2020/11/04 06:59

ご回答ありがとうございます。 2020.05.01 03:45 => 02:45になります。 処理の所参考になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問