【问题标题】:Extract filepaths from pandas DataFrame python从pandas DataFrame python中提取文件路径
【发布时间】:2019-09-09 07:15:03
【问题描述】:

我有一个 Excel 文件,其中包含列中文件夹的文件路径。可能有多个文件路径存储在一行中。 我可以像这样将excel文件读入pandas。

现在我要做的是逐行遍历我的 pandas DataFrame df 并提取存储的目录,以便我可以将它们用作其他功能的输入目录。

如果我使用 iloc 访问数据框中的行,我会得到一个类似 str 的对象,而我想要的每一行都是 list 类型的,所以我可以遍历它。

我的数据框中的变量格式示例。

import pandas as pd

path_1 = '[\'C:\\\\tmp_patients\\\\Pat_MAV_BE_B01_\']'
path_2 =  '[\'C:\\\\tmp_patients\\\\Pat_MAV_B16\', \'C:\\\\tmp_patients\\\\Pat_MAV_BE_B16_2017-06-30_08-49-28\']'
d = {'col1': [path_1, path_2]}
df = pd.DataFrame(data=d)
#or read directly excel 
# df= pd.read_excel(filepath_to_excel)


for idx in range(len(df)):
    paths = df['col1'].iloc[idx]
    for a_single_path in paths:
        print(a_single_path)
        # todo: process all the files found at the location "a single path" with os.walk

我用pd.read_excel()读取文件后数据的样子

【问题讨论】:

  • 为什么每个C:\左边都有一个“\”?您是从csvxlsx 文件中读取的吗?其中每一个都将在字符串中读取,df.explode() 将无法处理字符串。
  • @Trenton_M 当我使用 df['col1'].iloc[idx]` 访问df 的行时,左侧会添加一个“\”。我不明白为什么,因为原来的df 不存在。
  • @Trenton_M 更新了数据的屏幕截图。在df 的第 14 行,您会注意到我有 2 个单独的文件路径。
  • @Trenton_M .xlsx
  • @Trenton_M 解决了!非常感谢。

标签: python pandas dataframe


【解决方案1】:

如果你想要单个目录的行:

数据:

  • 注意使用的列名是file_path_lists,但问题截图中的列名是col1
from pathlib import Path
from ast import literal_eval

df = pd.read_excel('test.xlsx')

将行从str 转换为listexplode 每个list 到单独的行:

df.file_path_lists = df.file_path_lists.apply(literal_eval)
df2 = pd.DataFrame(df.explode('file_path_lists'))
df2.dropna(inplace=True)

print(df2.file_path_lists[0])
>>> 'C:\\tmp_patients\\Pat_MAV_BE_B01_'
  • 注意路径仍然是str

转换为pathlib对象:

df2.file_path_lists = df2.file_path_lists.apply(Path)
print(df2.file_path_lists[0])
>>> WindowsPath('C:/tmp_patients/Pat_MAV_BE_B01_')
  • 现在每个都是pathlib 对象。

访问各个目录:

for dir in df2.file_path_lists:
    print(dir)
    print(type(dir))

>>> C:\tmp_patients\Pat_MAV_BE_B01_
    <class 'pathlib.WindowsPath'>

    C:\tmp_patients\Pat_MAV_B16
    <class 'pathlib.WindowsPath'>

    C:\tmp_patients\Pat_MAV_BE_B16_2017-06-30_08-49-28
    <class 'pathlib.WindowsPath'>

打印在患者目录中找到的文件列表:

for dir in df2.file_path_lists:
    patient_files = list(dir.glob('*.*'))  # use .rglob if there are subdirs
    print(patient_files)

如果你想要lists 的行而不是每个目录的一行:

  • 跳过.explode
df = pd.read_excel('test.xlsx')
df.file_path_lists = df.file_path_lists.apply(literal_eval)

print(type(df.file_path_lists[0]))
>>> list

for row in df.file_path_lists:  # iterate the row
    for x in row:  # iterate the list inside the row
        print(x)

>>> C:\tmp_patients\Pat_MAV_BE_B01_
    C:\tmp_patients\Pat_MAV_B16
    C:\tmp_patients\Pat_MAV_BE_B16_2017-06-30_08-49-28

【讨论】:

    【解决方案2】:

    您的示例输入包含看起来像数组的字符串。我认为read_excel 不会这样做,所以你不需要下面的.apply(literal_eval) 调用。

    假设您使用的是 pandas 0.25 或更高版本,因此您可以使用 explode

    from ast import literal_eval
    
    path_1 = "['C:\\\\develop\\\\python-util-script\\\\Pat_MAV_B01']"
    path_2 =  "['C:\\\\develop\\\\python-util-script\\\\Pat_MAV_B16', 'C:\\\\develop\\\\python-util-script\\\\Pat_MAV_BE_B16_2017-06-30_08-49-28']"
    d = {'col1': [path_1, path_2]}
    df = pd.DataFrame(data=d)
    
    df['col1'].apply(literal_eval).explode()
    

    输出:

    0            C:\develop\python-util-script\Pat_MAV_B01
    1            C:\develop\python-util-script\Pat_MAV_B16
    1    C:\develop\python-util-script\Pat_MAV_BE_B16_2...
    Name: col1, dtype: object
    

    【讨论】:

    • read_excel 正是这样做的,因为我正在阅读我的df。我运行了您的代码,但没有任何变化:/。还修改了问题中的输入路径,最初我并没有完全按照pd.read_excel() 导入它们的方式复制它们。
    • 运行您的代码时出现的错误:ValueError: ("malformed node or string: 0 ['C:\\\\tmp_patients\\\\Pat_MAV_BE_B01_']\n1 NaN\nName: 0, dtype: object", 'occurred at index 0')
    • 更新了我使用pd.read_excel()将数据加载到df后的数据截图
    猜你喜欢
    • 2020-12-14
    • 2013-06-08
    • 1970-01-01
    • 2010-10-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多