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

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

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

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

pandas

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

Q&A

解決済

1回答

467閲覧

pandasで値を分割して代入したい

onakafunifuni

総合スコア7

Python 3.x

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

pandas

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

0グッド

0クリップ

投稿2020/03/17 10:46

編集2020/03/17 10:47

前提・実現したいこと

pandasでデータフレームの欠損値を、その次の値から特定の部分だけ抜き出して代入したいです。
以下の様なデータフレームが手元にあります。

python

1print(df)
dateattenddetail
2011-01-0145今日はレシーブ練習を中心に行った。
2011-01-0235試合を4マッチ、田中のミスが目立ち個別練習
2011-01-03NaNNaN
2011-01-0439<1/3>この日は大会に向けて引き続き試合を多く行った。<1/4>サーブ練習多め、次はラリー多くしてほしいとの要望あり。

detail欄にはテニスの練習のログを残しているようなデータです。
前日に記入漏れがあった場合、翌日に明記して合わせて書かせています。
翌日に明記した場合のdetail欄を2つに分け、1/3と1/4それぞれに代入し直したいと思っているのですが…
つまり、以下のようなデータフレームを最終的には作りたいと思っています。

dateattenddetail
2011-01-0145今日はレシーブ練習を中心に行った。
2011-01-0235試合を4マッチ、田中のミスが目立ち個別練習
2011-01-03NaNこの日は大会に向けて引き続き試合を多く行った。
2011-01-0439サーブ練習多め、次はラリー多くしてほしいとの要望あり。

簡略化のために短く書いていますが、実際は膨大な量なのでpythonで扱いたいと思っています。

発生している問題・エラーメッセージ・ソースコード

detailの列をリストとして扱い、<>で日付が変わっていることを利用して、splitで分けてそれぞれ新しいリストに代入した後、データフレームに合成しようと思いました。

python

1body = list(df["detail"]) 2 3n = 0 4 5l = [] 6 7for i in body : 8 if body[n] == "NaN" : 9 l.append(body[n+1].split(r'>')[2]) 10 else : 11 l.append(body[n]) 12 13 n = n + 1 14

しかし、返ってきたリスト(l)は中身が変わっていませんでした。
ループ内の記述(split辺り)が間違っているのでしょうか…必ずしもリストの代入で対応する必要もないでしょうか。
もし質問重複しておりましたら大変申し訳ありません。
初歩的な質問で申し訳ありませんが、どなたかご存知の方がいらっしゃったらお力添え願えないでしょうか?
どうぞよろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

lの中身が変わらないのは、判定式if body[n] == "NaN" :が違うためです。
NaNかどうかは、np.isnan(body[n])で判定します。
また、np.isnanは文字列の場合、エラーを返すので、

if type(body[n]) is float: # NaNはfloat判定される if np.isnan(body[n]):

に変えればエラーなく動作します。

また、このままだと1/3に「サーブ練習多め、次はラリー多くしてほしいとの要望あり。」、
1/4に、「<1/3>…<1/4>…。」とそのまま入ってしまいます。

おそらく、NaNのときは、その値(1/3のdetail)とその次の値(1/4のdetail)まで
if文の中で作ったほうが良いかと思います。
そちらはここでの回答はしませんが、また疑問があれば言ってください!

投稿2020/03/17 11:36

Matsui_hero

総合スコア346

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

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

onakafunifuni

2020/03/19 05:46

ありがとうございます! is floatで無事判定できました。 仰るとおり、このままループを回しますと1/4にそのまま文章が入ってしまうので、分岐で対応してみました。 n = 0 l = [] for i in body : if type(body[n]) is float: try : l.append(body[n+1].split(r'>')[1]) l.append(body[n+1].split(r'>')[2]) n = n + 1 except IndexError : l.append("NO DATA") else : l.append(body[n]) n = n + 1 if n == 2999 : break いくつか記入漏れがありそのエラーを補足しつつループを書くことができました。 丁寧なご回答大変助かりました!どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問