Создать фрейм данных из строк неравной длины - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть датафрейм имени файла и его пути в формате непрерывной строки:

Например:

 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: добавлено уточнение, что более короткий путь может быть заполнен нулями до максимальной длины.

1 Ответ

0 голосов
/ 26 февраля 2019

Может быть, я что-то упускаю, но почему это не работает для вас?

expanded = files['path'].str.split(os.path.sep, expand=True).fillna(0)
expanded = expanded.rename(columns=lambda x: 'level_' + str(x))
df = pd.concat([files.name, expanded], axis=1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...