我有一个文件名及其路径的数据框,其格式为连续字符串:
例如:
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 )
现在我用路径数组的条目填充空白框:
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小时。
首先,我想优化数据框的填充,第二步,我将拆分数据框,并行化操作,然后再次组装该框。
编辑:澄清了一个更短的路径,可以用零填充最大长度。
答案 0 :(得分:1)
也许我遗漏了一些东西,但是为什么这对您不起作用?
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)