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

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

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

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

Q&A

解決済

2回答

856閲覧

pandasのDataFrameの要素からindex名を取得する方法

ROKUNO

総合スコア10

pandas

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

0グッド

0クリップ

投稿2020/02/13 13:04

編集2020/02/13 15:21

Python初心者です。pandasのDataFrameを使ってデータ処理を練習しています。 Python3を使っています。

前提・実現したいこと

2つのDataFrame(1, 2)をベースにそれぞれのイベント時の年齢を出すようなプログラムを検討しています。

手元には加工用のデータとしてDataFrame1(出生日データ)、DataFrame2(各イベント時における年月日)。このDataFrame2の形をベースにしたまま、各イベントにおける年月日を、DataFrame1の情報を元に年齢に振り分けをしたいです。

DataFrame1とDataFrame2のindexはそれぞれ共通のindexを利用しているというという前提です。誕生日のデータはたくさんあり、その中に該当するidと誕生日が埋もれているイメージです。(追記)

#加工に使用する元データ #DataFrame1 # birthday #12 1910-01-01 #9 1980-02-03 : #8 1962-04-04 #10 1949-04-06 #DataFrame2 # high_school university1 university2 #8 1977-03-31 1985-03-31 1999-3-31 #9 1995-03-31 None None #10 1954-03-31 1964-3-31 None
#最終的に完成してほしい形(日時を年齢に置き換える) #DataFrame3 # high_school university1 university2 #8 15 23 42 #9 15 None None #10 15 22 None

実際に算出するステップとしては下記を考えました
1.DataFrame2.applymapの形で一気に処理することを想定
2.処理実行時に該当の要素について、その位置にある「インデックス名を取得」。
3.取得したインデックス名をDataFrame1で確認し該当する出生日を回収して、該当要素にある年月日と差し引きを行い、年齢を出す。
4.処理した結果DataFrame2に入っている出生日がイベント発生時の年齢に置き換わる(DataFrame3を取得)。

上記考えた際に「該当する要素のインデックス名を取得する方法」が実装できずにおり、アドバイスもらえると嬉しいです。また、もっと簡単な方法があれば是非教えてほしいです。

*イベント日時などは質問用に適当に作成したもので特に一貫性はありません。

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

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

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

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

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

meg_

2020/02/13 14:01

「1962-04-04」生まれの人が「1925-03-31」に高校を卒業したのですか? この場合はNoneになるということですか??
ROKUNO

2020/02/13 14:05

申し訳ございません、私の問題設定のミスになります。1962生まれので、1977年卒業に修正しました。混乱をさせてしまい申し訳ございません。
guest

回答2

0

Python

1DataFrame2.sub(DataFrame1["birthday"], 0)//pd.Timedelta(365, 'D')

追記

Python

1import io 2import pandas as pd 3 4text = """birthday 512,'1910-01-01' 69,'1980-02-03' 78,'1962-04-04' 810,'1949-04-06'""" 9text2 = """high_school,university1,university2 108,'1977-03-31','1985-03-31','1999-3-31' 119,'1995-03-31',, 1210,'1954-03-31','1964-3-31', 13""" 14 15df = pd.read_csv(io.StringIO(text)) 16df2 = pd.read_csv(io.StringIO(text2)).fillna(pd.NaT) 17 18df.iloc[:, 0] = pd.to_datetime(df.iloc[:, 0]).dt.strftime('%Y%m%d').astype(float) 19df2.iloc[:, 0] = pd.to_datetime(df2.iloc[:, 0]).dt.strftime('%Y%m%d').astype(float) 20df2.iloc[:, 1] = pd.to_datetime(df2.iloc[:, 1]).dt.strftime('%Y%m%d').astype(float) 21df2.iloc[:, 2] = pd.to_datetime(df2.iloc[:, 2]).dt.strftime('%Y%m%d').astype(float) 22 23print(df) 24# birthday 25# 12 19100101.0 26# 9 19800203.0 27# 8 19620404.0 28# 10 19490406.0 29print(df2) 30# high_school university1 university2 31# 8 19770331.0 19850331.0 19990331.0 32# 9 19950331.0 NaN NaN 33# 10 19540331.0 19640331.0 NaN

として、

Python

1result = df2.sub(df['birthday'], 0) // 10000 2print(result.astype('Int64')) 3# high_school university1 university2 4# 8 14 22 36 5# 9 15 <NA> <NA> 6# 10 4 14 <NA> 7# 12 <NA> <NA> <NA>

あるいは、

Python

1result = df2.sub(df['birthday'].reindex(df2.index), 0) // 10000 2print(result.astype('Int64')) 3# high_school university1 university2 4# 8 14 22 36 5# 9 15 <NA> <NA> 6# 10 4 14 <NA>

投稿2020/02/13 14:41

編集2020/02/14 01:33
kirara0048

総合スコア1399

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

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

kirara0048

2020/02/13 14:46

ああ、うるう年とかあるから365日で割って変換するのは駄目ですね()
ROKUNO

2020/02/13 15:19

回答有難うございます、いただいた形だとDataFrame2とDataFrame1はそれぞれ同じfeature spaceになっている前提でしょうか? >ValueError: operands could not be broadcast together with shapes というエラーが返ってきました。 私の書き方がわかりずらく申し訳ないのですが(後ほど修正してみます)、今回の課題設定では、DataFrame2の該当要素に対応するindexが、DataFrameのindexと共通ですが、形そのものが揃っているわけではないという状況になってます。
kirara0048

2020/02/14 00:27

indexの順番が異なっていてもラベルが共通していればそれに基づいてに計算されます。片方にしかないindexがある場合は「 DataFrame.reindex() 」を使ってください。
ROKUNO

2020/02/14 06:51

ありがとうございます!
guest

0

ベストアンサー

冗長かもしれませんが。

Python

1import pandas as pd 2import io 3import numpy as np 4 5text = """birthday 612,'1910-01-01' 79,'1980-02-03' 88,'1962-04-04' 910,'1949-04-06'""" 10 11text2 = """high_school,university1,university2 128,'1977-03-31','1985-03-31','1999-3-31' 139,'1995-03-31',, 1410,'1954-03-31','1964-03-31', 15""" 16 17df = pd.read_csv(io.StringIO(text)) 18df2 = pd.read_csv(io.StringIO(text2)) 19 20df3 = pd.merge(df2, df, left_index=True, right_index=True) 21 22df3['high_school'] = pd.to_datetime(df3['high_school']) 23df3['university1'] = pd.to_datetime(df3['university1']) 24df3['university2'] = pd.to_datetime(df3['university2']) 25df3['birthday'] = pd.to_datetime(df3['birthday']) 26 27df3['high_school2'] = df3['high_school'].dt.year 28df3['university1_'] = df3['university1'].dt.year 29df3['university2_'] = df3['university2'].dt.year 30df3['birthday2'] = df3['birthday'].dt.year 31 32df3 = df3.drop(['high_school', 'university1', 'university2', 'birthday'], axis=1) 33 34df3['high_school2'] = df3['high_school2'] - df3['birthday2'] 35df3['university1_'] = df3['university1_'] - df3['birthday2'] 36df3['university2_'] = df3['university2_'] - df3['birthday2'] 37 38df3 = df3.drop('birthday2', axis=1) 39 40df3 = df3.rename(columns={'high_school2':'high_school', 'university1_':'university', 'university2_':'university2'}) 41 42# high_school university university2 43#8 15 23.0 37.0 44#9 15 NaN NaN 45#10 5 15.0 NaN

投稿2020/02/13 15:13

meg_

総合スコア10760

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

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

ROKUNO

2020/02/14 06:52

ありがとうございます!こちらのコードに近い形で最終作成できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問