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

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

ただいまの
回答率

88.77%

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 502

mi2

score 33

やりたいこと

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で処理するのが一般的なのかもお教え頂けますと幸いです。

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

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

import pandas as pd
import re
import itertools

def func(row):

    a = row[0]

    # 空白を入れる
    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)

    # 列を追加
    for idx,val in enumerate(ret[1:]): # 先頭要素は追加不要
        row[idx+1] = val # 先頭列は追加不要(残しておく)

    return row

df = pd.DataFrame(['AA11BB','11AB22','DD11'])
df = df.apply(func,axis=1)
print(df)
"""
        0        1        2         3
0  AA11BB  AA11_BB  AA_11BB  AA_11_BB
1  11AB22  11AB_22  11_AB22  11_AB_22
2    DD11    DD_11      NaN       NaN
"""
df.to_csv('ret.txt',header=None,index=False)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/14 13:24

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

    キャンセル

  • 2019/05/14 14:57

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

    キャンセル

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/14 10:05

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

    キャンセル

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

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る