はじめに
配列に含まれている特定の文字列を一括置換する方法の一つとして残しておきます。
多次元配列を扱っている場合においても、内包表記などを用いれば簡単に置換できるかなと思います。
今回は拡張子を一括で変更する場合を考えてみます。
追記:
@shiracamus さんよりnumpyのchar.replace
メソッドを教えていただきました。ありがとうございました。
今回は、コメントに記載していただいたコードをそのまま引用させていただきます。
また、ファイル名にカンマが含まれていた場合に誤動作を起こしてしまうというご指摘もいただきました。numpyをもし使わない場合は、コメントにて記載してくださっている内包表記のみを使った方法を使うのがベストかと思います。
ご指摘、ご教授ありがとうございました。
方法(numpy.char.replaceを使った方法)
前述の通り、@shiracamus さんのコードの引用となります。ありがとうございました。
nunpyのドキュメントを一応追加で記載してきます。(numpy.char.replace)
numpyを使うならば、ご教授頂いた以下のchar.replace
メソッドを使うのが一番シンプルかつ簡単でベストだと思います。
import numpy as np
orig_list = ["test1.png", "test2.png", "test3.png"]
print(np.char.replace(orig_list, "png", "jpg"))
orig_arr = [["test11.png", "test12.png", "test13.png"],
["test21.png", "test22.png", "test23.png"],
["test31.png", "test32.png", "test33.png"]]
print(np.char.replace(orig_arr, "png", "jpg"))
orig_arr_3d = [
[["test111.png", "test112.png"],
["test121.png", "test122.png"],
["test131.png", "test132.png"]],
[["test211.png", "test212.png"],
["test221.png", "test222.png"],
["test231.png", "test232.png"]],
[["test311.png", "test312.png"],
["test321.png", "test322.png"],
["test331.png", "test332.png"]]
]
print(np.char.replace(orig_arr_3d, "png", "jpg"))
方法(joinを使った方法)
方法としてはリストを一度カンマ区切りの文字列に変換して、置換をします。
その後、置換された文字列を再度リストに戻すことで配列の一括変換を実現します。
追記
以下のコードでは、@shiracamus さんよりご指摘があった通り、ファイル名にカンマが入っていると誤動作を起こしてしまうという問題点があります。
そのため、@shiracamus さんよりご教授いただいた内包表記のみを使った方法を使うのがベストかと思います。
以下は、議事録として一応残しておきたいと思います。
1次元のリストの場合
orig_list = ["test1.png", "test2.png", "test3.png"]
# 一度joinで文字列に変換したのち、再度splitでリストに戻します。
replaced_list = ",".join(orig_list).replace("png", "jpg").split(",")
print(replaced_list)
# ['test1.jpg', 'test2.jpg', 'test3.jpg']
2次元のリストの場合
orig_arr = [["test11.png", "test12.png", "test13.png"],
["test21.png", "test22.png", "test23.png"],
["test31.png", "test32.png", "test33.png"]]
# 内包表記で同様の処理を記述します
replaced_arr = [",".join(l).replace("png", "jpg").split(",") for l in orig_arr]
print(replaced_arr)
# [['test11.jpg', 'test12.jpg', 'test13.jpg'],
# ['test21.jpg', 'test22.jpg', 'test23.jpg'],
# ['test31.jpg', 'test32.jpg', 'test33.jpg']]
関数として括りだす
置換する箇所を関数として括りだせばもっとシンプルになります。
また、次元数を簡単に取得するためにnumpyを使うことでn次元の配列にも容易に対応できます。
(そんな高次元で使うことはないと思うのですが、一応残しておきます)
それでは、組み込み関数のreplaceをラッピングするような形で関数を定義して書き直してみます。
import numpy as np
# Ref. built-in::str.replace(old, new[, count])
def replace_for_arr(data: np.ndarray, old, new):
'''2次元以上のリストのときは再帰します'''
if len(data.shape) >= 2:
return [replace_for_arr(d, old, new) for d in data]
return ",".join(data).replace(old, new).split(',')
# ===== <1次元の場合> =====
orig_list = ["test1.png", "test2.png", "test3.png"]
print(replace_for_arr(np.asarray(orig_list), "png", "jpg"))
# ['test1.jpg', 'test2.jpg', 'test3.jpg']
# ===== <2次元の場合> =====
orig_arr = [["test11.png", "test12.png", "test13.png"],
["test21.png", "test22.png", "test23.png"],
["test31.png", "test32.png", "test33.png"]]
print(replace_for_arr(np.asarray(orig_arr), "png", "jpg"))
# [['test11.jpg', 'test12.jpg', 'test13.jpg'],
# ['test21.jpg', 'test22.jpg', 'test23.jpg'],
# ['test31.jpg', 'test32.jpg', 'test33.jpg']]
# ===== <3次元の場合> =====
orig_arr_3d = [
[["test111.png", "test112.png"],
["test121.png", "test122.png"],
["test131.png", "test132.png"]],
[["test211.png", "test212.png"],
["test221.png", "test222.png"],
["test231.png", "test232.png"]],
[["test311.png", "test312.png"],
["test321.png", "test322.png"],
["test331.png", "test332.png"]]
]
print(replace_for_arr(np.asarray(orig_arr_3d), 'png', 'jpg'))
# [[['test111.jpg', 'test112.jpg'],
# ['test121.jpg', 'test122.jpg'],
# ['test131.jpg', 'test132.jpg']],
# [['test211.jpg', 'test212.jpg'],
# ['test221.jpg', 'test222.jpg'],
# ['test231.jpg', 'test232.jpg']],
# [['test311.jpg', 'test312.jpg'],
# ['test321.jpg', 'test322.jpg'],
# ['test331.jpg', 'test332.jpg']]]