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

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

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

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

pandas

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

Q&A

解決済

2回答

550閲覧

TSVファイルのフィールドの再分割の繰り返し方法

MakotoAkai

総合スコア7

Python 3.x

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

pandas

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

1グッド

0クリップ

投稿2022/01/18 13:06

編集2022/01/18 13:19

PythonでTSVファイルを読み込んでいます。
このTSVファイルのフィールドは(ここではCSVとして,区切りで表記します)

1,108.5,3.2, Var1=10.9, Var2=9.8 ......
のように、数値だけのフィールドと、変数名=値の形式のフィールドが混在しています。
この後者のフィールドから変数名を外して、数値のみを取り出したいのですが、スマートな実装方法が分かりません。

df=pd.read_csv('Opt.dat',sep='\t',names=('ID','EQ','Trades','PF','EV','DD$','DD%','ExitL','RR','SL','MAGIC','Lots','MA1','MA2','MA3','Int','MAType','MaxPos','Nanpin'))

df['ExitL']=(df['ExitL'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(float))
df['RR']=(df['RR'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(float))
df['SL']=(df['SL'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(float))
df['MAGIC']=(df['MAGIC'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['Lots']=(df['Lots'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(float))
df['MA1']=(df['MA1'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['MA2']=(df['MA2'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['MA3']=(df['MA3'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['Int']=(df['Int'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['MAType']=(df['MAType'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['MaxPos']=(df['MaxPos'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(int))
df['Nanpin']=(df['Nanpin'].str
.split('=')
.dropna()
.apply(lambda x: x[1])
.astype(float))

のように、該当する変数をひとつづつ処理するような泥臭いやり方をしているのですが、
こういう同じような処理を上手にまとめて流す良い方法はありませんでしょうか?

また、各ブロックの.apply(lambda x: x[1])の部分なのですが、
tmp=df['xxx'].str.split('=')
df['xxx']=tmp.iloc[:,1]
のような形で実装しようとすると2行目の処理のところで、indexがおかしいと言われます。
te_key_length
raise IndexingError("Too many indexers")
pandas.core.indexing.IndexingError: Too many indexers

df['xxx']=tmp.iloc[1]
ならとおりますが、これでは2列目(縦)では無く、2行目(横)が出力されてしまいます。
[xxx, 1.88]
みたいな感じで一行分だけが出力される感じです。

print(tmp)すると
4246 [xxx, 3 ]
4245 [xxx, 2.9 ]
4244 [xxx, 2.8 ]
4243 [xxx, 2.7 ]
のような感じなので、split('=')自体は正しく動いているように見えます。

正しくはどのように書けば良いのでしょうか?

melian👍を押しています

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

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

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

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

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

y_waiwai

2022/01/18 15:24

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
guest

回答2

0

ベストアンサー

Opt.dat

tsv

11 108.5 3.2 Var1=10.9 Var2=9.8 Var3=8.3 100 200 Var4=6.9 22 Var5=10.9 0 Var6=3.4 1 Var7=2.3 2 Var8=5.7 3

python

1import pandas as pd 2 3df = pd.read_table('Opt.dat', sep=r'\t(?:\w+=)?', header=None, engine='python') 4 5print(df) 6# 0 1 2 3 4 5 6 7 8 7# 0 1 108.5 3.2 10.9 9.8 8.3 100 200.0 6.9 8# 1 2 10.9 0.0 3.4 1.0 2.3 2 5.7 3.0 9 10pd.set_option('display.max_columns', None) 11print(df.applymap(type)) 12# 0 1 2 3 13# 0 <class 'int'> <class 'float'> <class 'float'> <class 'float'> 14# 1 <class 'int'> <class 'float'> <class 'float'> <class 'float'> 15# 16# 4 5 6 7 17# 0 <class 'float'> <class 'float'> <class 'int'> <class 'float'> 18# 1 <class 'float'> <class 'float'> <class 'int'> <class 'float'> 19# 20# 8 21# 0 <class 'float'> 22# 1 <class 'float'>

投稿2022/01/18 14:49

編集2022/01/18 15:20
melian

総合スコア19798

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

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

MakotoAkai

2022/01/19 21:08

ありがとうございます。 sep=r'\t(?:\w+=)?' タブだけではなく、英単語=の文字列も区切りとみなして一気に分割するという発想はありませんでした。 こんな方法もあるんですね。使い道が広そうな発想で、勉強になりました。 ありがとうございました。
guest

0

intにしたい列とfloatにしたい列があるならその指定は必要ですので、以下のようにする程度でしょう。

python

1>>> print(df) 2 i j x k y 30 0 a=0 b=90.0 c=5 d=0.5 41 2 a=0 b=92.0 c=0 d=1.9 52 1 a=1 b=91.1 c=9 d=3.6 63 1 a=0 b=91.0 c=-3 d=6.8 74 2 a=2 b=92.2 c=8 d=2.1 8>>> to_int = ['j', 'k'] 9>>> to_float = ['x', 'y'] 10>>> 11>>> for c in to_int: 12... df[c] = df[c].str.replace('.+=', '', regex=True).astype(int) 13... 14>>> for c in to_float: 15... df[c] = df[c].str.replace('.+=', '', regex=True).astype(float) 16... 17>>> print(df) 18 i j x k y 190 0 0 90.0 5 0.5 201 2 0 92.0 0 1.9 212 1 1 91.1 9 3.6 223 1 0 91.0 -3 6.8 234 2 2 92.2 8 2.1

投稿2022/01/18 13:36

ppaul

総合スコア24666

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

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

MakotoAkai

2022/01/19 21:11

なるほど、区分けするフィールドの名前を配列として持っておいて、それをこういう形で呼び出せば良かったのですね。 前者のイメージはあったのですが、後者の具体的なやり方が全然分からなかったので、助かりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問