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

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

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

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

pandas

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

Q&A

解決済

2回答

1895閲覧

リスト(df)内の要素全てに対して処理を適応し、不揃いの列を追加したい

mi2

総合スコア63

Python 3.x

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

pandas

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

0グッド

0クリップ

投稿2019/05/13 14:09

やりたいこと

AA11BB
11AB22
DD11ZZ

このデータから数字とアルファベットの間に区切りを入れて、

<1列目> <2列目> <3列目> <4列目>
AA11BB AA_11_BB AA11_BB AA_11BB
11AB22 11_AB_22 11AB_22 11_AB22
DD11ZZ DD_11

のように、区切りを入れた上で列は不揃いの複数の組合せをdfで取得し出力したいと考えています。

文字列については複数の組み合わせを作成することが出来、これをリストもしくはdfで複数行で操作したいのですが、リスト内の各文字列に対応してリスト(df)の数(列)を増やす実装方法に困っています。

コード

# 文字列のリストを定義 a = 'AA11BB' # 空白を入れる b = re.sub(r'((?<=\d)\D|(?<=\D)\d)', r' \1', a) # スペース区切り lst = b.split(' ') # アンダースコア追加 ret = [] for tpl in itertools.product(['','_'],repeat=len(lst)-1): p = lst[0] for t,l in zip(tpl,lst[1:]): p += t + l ret.append(p) # 重複がある場合削除 ret = list(set(ret)) # dfに追加 df = pd.DataFrame(ret).T # csv出力(df) df.to_csv('df.csv', encoding='utf_8_sig')

現状は、上記'AA11BB'のみについて対応できています。

# 複数行対応したい a = pd.read_csv('test.csv') a = a.values.tolist() print(a) # [['AA11BB'],['11AB22'],['DD11']]

a = [['AA11BB'],['11AB22'],['DD11']]のようにリストのリストを使って1行ずつ文字列に対応させ
たいのですが、ここからがうまくいかず現状1行しか対応できない状況です。

複数行対応させるためのよい方法等がございましたらご教示頂けたらと思っております。
また、今回のような処理の場合、listでcsv出力まで処理するのが一般的なのか、dfで処理するのが一般的なのかもお教え頂けますと幸いです。

何卒よろしくお願い申し上げます。

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

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

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

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

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

guest

回答2

0

ベストアンサー

Pandasでやってみました。処理を関数にまとめ、applyで各行ごとに処理します。
ただしKojiDoiさんのおっしゃるように、今回のケースではメモリ効率、速度からも単純なテキスト入出力でよいかと思います。

Python

1import pandas as pd 2import re 3import itertools 4 5def func(row): 6 7 a = row[0] 8 9 # 空白を入れる 10 b = re.sub(r'((?<=\d)\D|(?<=\D)\d)', r' \1', a) 11 12 # スペース区切り 13 lst = b.split(' ') 14 15 # アンダースコア追加 16 ret = [] 17 for tpl in itertools.product(['','_'],repeat=len(lst)-1): 18 p = lst[0] 19 for t,l in zip(tpl,lst[1:]): 20 p += t + l 21 ret.append(p) 22 23 # 列を追加 24 for idx,val in enumerate(ret[1:]): # 先頭要素は追加不要 25 row[idx+1] = val # 先頭列は追加不要(残しておく) 26 27 return row 28 29df = pd.DataFrame(['AA11BB','11AB22','DD11']) 30df = df.apply(func,axis=1) 31print(df) 32""" 33 0 1 2 3 340 AA11BB AA11_BB AA_11BB AA_11_BB 351 11AB22 11AB_22 11_AB22 11_AB_22 362 DD11 DD_11 NaN NaN 37""" 38df.to_csv('ret.txt',header=None,index=False)

投稿2019/05/13 16:49

編集2019/05/14 05:56
can110

総合スコア38234

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

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

mi2

2019/05/14 04:24

ありがとうございます。 処理を関数で固めてdf.applyの引数に関数を指定することで想定していた処理が出来るということが理解できました。
can110

2019/05/14 05:57

一部の要素が列に追加できていなかったためコード修正しました。
guest

0

listでcsv出力まで処理するのが一般的なのか、dfで処理するのが一般的なのかもお教え頂けますと幸いです。

本件のように、各行の処理がそれぞれの行の中で完結している(他の行の内容によって処理内容が変わったりしない)場合は、一行読んでは何か処理をして吐き出すという形にした方がメモリが節約できます。

with open("input.txt", "r") as f: for l in f: # lに対して処理

大枠はこんな感じで、これに先のコードを組み合わせればよいはずです。頑張ってください。

投稿2019/05/13 16:15

KojiDoi

総合スコア13669

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

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

mi2

2019/05/14 01:05

ありがとうございます。 メモリの観点があるのですね。 とても勉強になりました。 感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問