Разделить список путей к файлам на вложенные списки на основе вложенной строки в filepath

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть большой список путей к файлам, указывающий на файлы CSV.

 ...SomeFileIDon'tNeed.csv
01SMPL_1.csv
01SMPL_2.csv
01SMPL_3.csv
01SMPL_4.csv
01SMPL_5.csv
01SMPL_6.csv
02SMPL_1.csv
02SMPL_2.csv
02SMPL_3.csv
02SMPL_4.csv
02SMPL_5.csv
02SMPL_6.csv
  

Я хочу разделить этот список на вложенные списки следующим образом

 [["01SMPL_1.csv","02SMPL_1.csv"],["01SMPL_2.csv","02SMPL_2.csv"],["01SMPL_3.csv","02SMPL_3.csv"],...]
  

Это потому, что мне нужно объединить все похожие файлы в фреймы данных. Таким образом, все файлы, заканчивающиеся на _1, будут одним df, а файлы, заканчивающиеся на _2, будут другим df и т.д.

Я написал код, который разделит исходный список на вложенные списки, которые я хочу, но это не очень эффективно. Я ищу лучший способ

 #where f is the original list of file paths
dfs=[]
for i in range(len(f)):
    temp=[]
    for file in f:
        count="_" str(i)
        if count in file:
            temp.append(file)
    dfs.append(temp)
  

Комментарии:

1. Шаблон _someNumber всегда один и тот же, или вам нужно сначала определить его?

2. Он всегда будет заканчиваться _someNumber !

3. @Gingerhaze они все .csv ?

4. @alani да, это все файлы CSV

Ответ №1:

Как насчет наличия в словаре такого. Он будет иметь дело с разделом «_xx» независимо от того, сколько времени занимает идентификационный номер.

 paths = ["01SMPL_1.csv","01SMPL_2.csv","01SMPL_3.csv","01SMPL_4.csv","01SMPL_4.csv","01SMPL_4.csv","001SMPL_5.csv"]


split_paths = {}

#iterate paths
for path in paths:
    #get key without .csv
    loc = path.find("_")
    key = path[loc:].replace(".csv","")
    #add to dictionary
    if key in split_paths.keys():
        split_paths[key].append(path)
    else:
        split_paths[key] = [path]

print(split_paths)
  

вывод:

 {'_1': ['x01SMPL_1.csv'], '_2': ['x01SMPL_2.csv'], '_3': ['x01SMPL_3.csv'], '_4': ['x01SMPL_4.csv', 'x01SMPL_4.csv', 'x01SMPL_4.csv'], '_5': ['001SMPL_5.csv']}
  

Тогда, если вам действительно нужно это в списке.

 [v for k,v in split_paths.items()]
  

вывод:

 [['x01SMPL_1.csv'],
 ['x01SMPL_2.csv'],
 ['x01SMPL_3.csv'],
 ['x01SMPL_4.csv', 'x01SMPL_4.csv', 'x01SMPL_4.csv'],
 ['001SMPL_5.csv']]
  

Ответ №2:

Это можно было бы сделать, используя комбинацию синтаксического анализа регулярных выражений для извлечения номера индекса, с последующей сортировкой 2-х кортежей (индекс, имя файла), а затем с помощью itertools.groupby — с помощью ключевой функции для groupby , которая возвращает номер индекса (см. lambda Функцию ниже).

 import re
from itertools import groupby

def get_index(filename):
    match = re.search('_(d ).csv$', filename)
    if match:
        return int(match.group(1))
    else:
        return None


def get_filenames_with_index(index_file):
    with open(index_file) as f:
        for line in f:
            filename = line.rstrip('n')
            index = get_index(filename)
            if index is not None:
                yield (index, filename)


index_file = 'filelist'

dfs = []
for i, files_with_indexes in groupby(sorted(get_filenames_with_index(index_file)),
                                     lambda t:t[0]):
    
    dfs.append([file for index, file in files_with_indexes])

print(dfs)
  

Это дает (когда filelist содержит список, показанный в вопросе):

 [['\001SMPL_1.csv', '\002SMPL_1.csv'], ['\001SMPL_2.csv', '\002SMPL_2.csv'], ['\001SMPL_3.csv', '\002SMPL_3.csv'], ['\001SMPL_4.csv', '\002SMPL_4.csv'], ['\001SMPL_5.csv', '\002SMPL_5.csv'], ['\001SMPL_6.csv', '\002SMPL_6.csv']]
  

(Примечание: здесь не совсем ясно из вопроса, есть ли у вас буквальные обратные косые черты или escape-последовательности в ваших именах файлов, но все, что у вас есть, будет сохранено в выходных данных.)

Ответ №3:

 import operator
f = ["01SMPL_1.csv",
"01SMPL_2.csv",
"01SMPL_3.csv",
"01SMPL_4.csv",
"01SMPL_5.csv",
"01SMPL_6.csv",
"02SMPL_1.csv",
"02SMPL_2.csv",
"02SMPL_3.csv",
"02SMPL_4.csv",
"02SMPL_5.csv",
"02SMPL_6.csv"]

temp = []
for file in f:
    firstdelpos= file.find("_")
    lastdelpos = file.find(".")
    a = int(file[firstdelpos 1:lastdelpos])
    temp.append([file,a])
sorted_list = sorted(temp, key=operator.itemgetter(1))        
dfs=[]
dupl = []
for i in range(len(sorted_list)-1):
    if(sorted_list[i][1] == sorted_list[i 1][1]):
        if(dupl == []):     
            dupl.append([sorted_list[i][0],sorted_list[i 1][0]])    
        else:
            
            dupl.append(sorted_list[i 1][0])
    else:
        if (dupl==[]):
            dupl.append(sorted_list[i][0])        
        dfs.append(dupl)
        dupl = []
    if(i==len(sorted_list)-2):
                
        if (dupl==[]):
            dupl.append(sorted_list[i 1][0])        
        dfs.append(dupl)