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

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

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

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

Q&A

解決済

1回答

345閲覧

DataFrameからの値抽出アルゴリズム

ba-ba-ba

総合スコア16

Python

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

0グッド

0クリップ

投稿2019/01/25 15:25

編集2019/01/26 13:43

###DataFrameからの値抽出アルゴリズムで困っています.
下記のようなデータフレームに置いて
イメージ説明

イメージ説明

各ID毎のa-dの値を抽出したい
抽出する値は最も古いもの

###例
ID272083の場合は
a,cは2017-04-03の値(a:16662,c:2800.7)を採用するが
dは2017-04-04の値(133.0)
bは更に新しいものを検索していき値があればそれを採用し,なければnanを採用する

発生している問題

IDのunique数と同じデータ数を取得しなければならないが,下記のコードでは取得する数が少ない.
ID:500,c2:440
となってしまう.
nの場所が間違っているような気がしますが…

該当のソースコード

python

1#データの読み込み 2test = pd.read_csv() 3test["date"] = pd.to_datetime(test['date']) 4test = test.set_index(["ID","date"]) 5 6#今現在の状況 7test = test.reset_index(["ID","date"]) 8ID_uni = test["ID"].unique() 9test = test.fillna(0) 10 11a1 = [] 12b1 = [] 13c2 = [] 14d3 = [] 15for i in ID_uni: 16 #n = 1 17 for j in range(len(test["ID"])): 18 print(n) 19 if test["ID"][j] == i: 20 #a = test["a"][j] 21 #b = test["b"][j] 22 c = test["c"][j] 23 #d = test["d"][j] 24 if c != 0: 25 c2.append(c) 26 break 27 elif n == test['ID'].value_counts()[i]: 28 c2.append(0) 29 break 30 n += 1 31 32ソースコード

試したこと

階層をはずしたりし,試行錯誤していますが,うまくいきません.

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

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

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

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

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

can110

2019/01/25 22:10

入力元のデータフレームの構造が不明なので、提示部分のデータを生成するような簡単なサンプルコードを提示すると回答得られやすいと思います。 また、値の採用ルールですがNaNまたは0は無視するという感じでしょうか?
ba-ba-ba

2019/01/26 10:29

ご指摘いただきありがとうございます. そうです,NaNと0は無視します.
guest

回答1

0

ベストアンサー

こんにちは。
全データをチェックしてもいいですが、私なら下の手順で求めます。

for IDごと  for a~d列ごと   あるIDのある列の値がNanでも0でもないものを抽出    そのうちの最古日付の値を保存(なければNan)

【追記】
解決したようでなによりです。
サンプルを実装してみたので、こういう方法もありだなと思って頂ければ幸いです。
以下、サンプルCSV、コード、結果出力。

csv

1id date val 21 2017-01-01 NaN 31 2017-01-02 1 42 2017-01-01 2 52 2017-01-02 3 63 2017-01-01 0 73 2017-01-02 NaN

Python

1import pandas as pd 2 3df = pd.read_csv('data.csv', delimiter='\t') 4id_list = df.id.unique() 5 6# 値が0かNaNの行を削除 7df = df.loc[df.val != 0] 8df = df.dropna() 9 10for id in id_list: 11 df_id = df.loc[df.id == id] # idごとのDataFrame 12 13 if len(df_id) == 0: 14 print('id:{} is val:Nan'.format(id)) 15 else: 16 # 日付が最小の行を抽出 17 min_row = df_id.loc[df_id.date == df_id.date.min()] 18 print('id:{} is val:{}'.format(id, min_row.values[0][2]))

sh

1id:1 is val:1.0 2id:2 is val:2.0 3id:3 is val:Nan

投稿2019/01/26 02:16

編集2019/01/26 14:33
firedfly

総合スコア1131

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

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

ba-ba-ba

2019/01/26 10:43 編集

回答ありがとうございます. for IDとは for i in test[ID]: ということでしょうか? この場合階層構造は外した方がいいのでしょうか?
firedfly

2019/01/26 13:41

for i in ID_uni: ですね。 正直、どうやっても(効率はさておき)できるので、なにがベストということはないです。 DataFrame は列方向の演算が高速なので Group by など使うとよい、というぐらいで。
ba-ba-ba

2019/01/26 13:49

ありがとうございます. 今現状上記の様なコードなのですが,取得数が合わず困っています. おかしなところお気づきになりましたら,ご指摘お願い致します.
firedfly

2019/01/26 13:52

「ID:500,c2:440」では多いか少ないか判断できないので 元データ(やそれに類似したサンプルの)CSVと実行結果をセットでもらえたらアドバイスします。
ba-ba-ba

2019/01/26 14:27

nの位置を訂正することで解決致しました. 本当にありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問