如何在一个列表中分组以匹配python 3中其他字符串列表中的元素的字符串
我得到了744个图像文件,名称如下:“任务\代码\合作\日期1 \日期2 \ 01 \ T1/2 \ Bnumber.TIF”。如以下列表所示,例如:如何在一个列表中分组以匹配python 3中其他字符串列表中的元素的字符串,python,python-3.x,Python,Python 3.x,我得到了744个图像文件,名称如下:“任务\代码\合作\日期1 \日期2 \ 01 \ T1/2 \ Bnumber.TIF”。如以下列表所示,例如: files = [ 'LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', #--¬ 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF', #---note match except in the 'coord' part 'LT05_L1TP_0260
files = [
'LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', #--¬
'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF', #---note match except in the 'coord' part
'LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF',
'LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF',
'LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']
#---------^-----^
# 9 15
目标是将“任务代码”和“日期1\u日期2\u 01\u T1/2\u Bnumber.TIF”匹配的文件分组到子列表中,然后输出如下数组:
ord_files=[
['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF','LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF','LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF','']]
有些文件有一对、三元组或单独存在。
我的想法是从一个新的列表(mo_文件)中的coord部分删除字符串,这样可以很容易地进行筛选,然后使用条件创建otput列表(ord_文件)
到目前为止,在这种情绪下,我尝试过以下方法:
for k in range(len(files)):
mo_files[k][:] = files[k][9] + files[k][15]
只有我收到错误,如索引器错误:列表索引超出范围
有一种更简单或更好的方法吗
谢谢。您可以使用:
d = {} # you can also use collections.defaultdict
for f in files:
d.setdefault(tuple(e for i, e in enumerate(f.split('_')) if i != 2), []).append(f)
list(d.values())
from collections import defaultdict
d = defaultdict(list)
for f in files:
d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)
list(d.values())
输出:
[['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF',
'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF'],
['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']]
或者您可以使用:
from collections import defaultdict
d = defaultdict(list)
for f in files:
d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)
list(d.values())
此版本的机器人速度更快您可以使用:
d = {} # you can also use collections.defaultdict
for f in files:
d.setdefault(tuple(e for i, e in enumerate(f.split('_')) if i != 2), []).append(f)
list(d.values())
from collections import defaultdict
d = defaultdict(list)
for f in files:
d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)
list(d.values())
输出:
[['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF',
'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF'],
['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF'],
['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'],
['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']]
或者您可以使用:
from collections import defaultdict
d = defaultdict(list)
for f in files:
d[tuple(e for i, e in enumerate(f.split('_')) if i != 2)].append(f)
list(d.values())
如果您喜欢熊猫,则此版本的机器人速度更快:
import pandas as pd
df = pd.DataFrame(files, columns=["filename"])
# indeed define a "key" that is the whole string without 'coord' part
df["key"] = df.filename.apply(lambda s: s[:9]+s[16:])
现在,您所要做的就是groupby
并使用list
进行聚合:
>>> df.groupby("key").filename.apply(list).values
array([list(['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']),
list(['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF']),
list(['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF']),
list(['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'])],
dtype=object)
顺便说一句,如果您不确定700多个文件中的索引是否会更改,那么更稳定的解决方案是使用\uu
-拆分:
df["key"] = df.filename.apply(
lambda filename: "_".join([part for idx, part in enumerate(filename.split("_")) if idx != 2])
)
如果你喜欢熊猫:
import pandas as pd
df = pd.DataFrame(files, columns=["filename"])
# indeed define a "key" that is the whole string without 'coord' part
df["key"] = df.filename.apply(lambda s: s[:9]+s[16:])
现在,您所要做的就是groupby
并使用list
进行聚合:
>>> df.groupby("key").filename.apply(list).values
array([list(['LC08_L1TP_026047_20150713_20170226_01_T1_B1.TIF']),
list(['LM02_L1TP_028046_19760327_20180424_01_T2_B6.TIF', 'LM02_L1TP_028047_19760327_20180424_01_T2_B6.TIF']),
list(['LT05_L1TP_026046_19951010_20170106_01_T1_B5.TIF']),
list(['LT05_L1TP_026047_19951010_20170107_01_T1_B5.TIF'])],
dtype=object)
顺便说一句,如果您不确定700多个文件中的索引是否会更改,那么更稳定的解决方案是使用\uu
-拆分:
df["key"] = df.filename.apply(
lambda filename: "_".join([part for idx, part in enumerate(filename.split("_")) if idx != 2])
)
我猜
mou文件[k]
是您的索引错误。您可能需要使用mo\u files.append()
。不相关的,我建议写慢一点,而不是复杂的一行。例如,实现函数get_mission
,该函数接收图像文件的名称并返回任务的名称。您的预期输出是错误的,因为在第二个列表中,date2是20170106
和20170107
@kederrac True!,第一次没有注意到,但修复了添加“和我!”4` . 谢谢。我猜mou文件[k]
是您的索引错误。您可能需要使用mo\u files.append()
。不相关的,我建议写慢一点,而不是复杂的一行。例如,实现函数get_mission
,该函数接收图像文件的名称并返回任务的名称。您的预期输出是错误的,因为在第二个列表中,date2是20170106
和20170107
@kederrac True!,第一次没有注意到,但修复了添加“和我!”4` . 谢谢。优雅的回答。我想作者应该按照mission\u code
和date1\u date2\u 01\u T1/2\u Bnumber.TIF
进行分组。因此,f.split(“”,1)[0]
似乎不是正确的键,但是“”.join([part for idx,part in enumerate(filename.split(“”))如果idx!=2])
会这样做。你觉得怎么样?@Arnaud thx我已经更新了我的答案,我使用了元组(e代表I,e在enumerate(f.split(“'))中,如果I!=2)
根据我的理解,除了split
优雅的答案给出的第二个元素外,其余都是关键。我想作者应该按照mission\u code
和date1\u date2\u 01\u T1/2\u Bnumber.TIF
进行分组。因此,f.split(“”,1)[0]
似乎不是正确的键,但是“”.join([part for idx,part in enumerate(filename.split(“”))如果idx!=2])
会这样做。你觉得怎么样?@Arnaud thx我已经更新了我的答案,并且我使用了元组(e代表I,e在枚举(f.split(“”))中,如果I!=2)
根据我的理解,除了split