У меня есть датафрейм имени файла и его пути в формате непрерывной строки:
Например:
files = pandas.Dataframe((
name path
0 file1.txt \\drive\folder1\folder2\folder3\...\file1.txt
1 file2.pdf \\drive\folder1\file2.pdf
2 file3.xls \\drive\folder1\folder2\folder3\...\folder21\file3.xls
n ... ...))
Размер кадра составляет около 1,02E + 06записей, глубина накопителя составляет не более 21 папки, но сильно варьируется.Цель состоит в том, чтобы иметь фрейм данных в формате:
name level1 level2 level3 level4 ... level21
0 file.txt folder1 folder2 folder3 0 ... 0
1 file.pdf folder1 0 0 0 ... 0
2 file3.xls folder1 folder2 folder3 folder4 ... folder21
...
Я разделил строку расположения файла и создал массив с, который можно заполнить нулями, если путь короче:
files = files.assign(plist=files['path'].iloc[:].apply(path_split))
def path_split(name):
return np.array(os.path.normpath(name).split(os.sep)[7:])
Добавьте столбец с номером папки в пути к файлам:
files = files.assign(len_plist = files.plist.iloc[:].map(len))
Проблема здесь в том, что строка пути разделения создает вложенные массивы внутри фрейма данных.Затем пустой Dataframe с количеством столбцов в количестве папок (21 здесь) и строк в соответствии с количеством файлов (1.02E + 06 здесь):
max_folder = files['len_plist'].max() # get the maximum amount of folders
levelcos = [ 'flevel_{}'.format(i) for i in np.arange(max_folder)]
levels = pd.DataFrame(np.zeros((files.shape[0],max_folder)),
columns =levelcos, index = files.index )
и теперь я заполняю пустой кадрс записями массива path:
levels = fill_rows(levels,files.plist.values)
def fill_rows(df,array):
for i,row in enumerate(array):
df.iloc[i,:row.shape[0] - 1] = row[:-1]
return df
Это занимает много времени, поскольку изменяющаяся длина массивов путей не позволяет сразу же векторизовать решение.Если мне нужно зациклить все строки данных 1.02E + 06 в кадре данных, это займет не менее 34 часов, может быть, до 200 часов.
Во-первых, я хочу оптимизировать заполнение кадра данных и на втором шагеЯ разбил бы фрейм данных, распараллелил операции и затем снова собрал фрейм.
edit: добавлено уточнение, что более короткий путь может быть заполнен нулями до максимальной длины.