如何从一列路径中获取基本文件名

问题描述 投票:0回答:5

我有一个带有文件路径列的 DataFrame。

我只想改成文件名

我的 DataFrame 看起来像:

df = pd.DataFrame({
    'Sr No': [18, 19, 20],
    'Email': ['[email protected]', '[email protected]', '[email protected]'],
    'filename': [r'C:/Users\Test.csv', r'C:/Users\Test1.csv',
                 r'C:/Users\Test1.csv']
})
高级号 电邮 文件名
18 [email protected] C:/用户\测试.csv
19 [email protected] C:/用户\Test1.csv
20 [email protected] C:/用户\Test1.csv
  1. 文件名应该只有 Test 和 Test1
  2. 只需两次写 [email protected] i.e. 一次用于 Test.csv,另一次用于 Test1.csv.

简而言之,我的输出应该是这样的:

df = pd.DataFrame({
    'Sr No': [18, 19, 20],
    'Email': ['[email protected]', '[email protected]', '[email protected]'],
    'filename': ['Test', 'Test1', 'Test1']
})
高级号 电邮 文件名
18 [email protected] 测试
19 [email protected] 测试1
20 [email protected] 测试1

我想用 python 和 pandas DataFrame 来做。

我在“文件名”列中有 100 行。

我尝试使用:

import os

import glob

myfile = os.path.basename('C:/Users/Test.csv')
os.path.splitext(myfile)
print(os.path.splitext(myfile)[0])

但是它只对一个路径有用,如何应用到整个列?

python pandas path filenames
5个回答
4
投票

使用

pandas.Series.apply
遍历列,并将结果分配给新列。

df["filename"] = df["filename"].apply(os.path.basename)

df["filename"] = df["filename"].apply(lambda path: os.path.basename(path))

例子:

>>> df
   Sr No          Email            filename
0     18  [email protected]   C:/Users\Test.csv
1     19  [email protected]  C:/Users\Test1.csv
2     20  [email protected]  C:/Users\Test1.csv

>>> df["filename"] = df["filename"].apply(os.path.basename)
>>> df
   Sr No          Email   filename
0     18  [email protected]   Test.csv
1     19  [email protected]  Test1.csv
2     20  [email protected]  Test1.csv

还有一个选项使用

Path('C:/Users\Test.csv').name
模块中的
pathlib
,但这比
os.path.basename
慢,因为
pathlib
必须将
string
转换为
pathlib
对象。

如果文件名前的斜杠一致,最快的选择是

pandas.Series.str.split
(例如
df['filename'].str.split('\\', expand=True).iloc[:, -1]
)。

python 3.11.2
pandas 2.0.0

中测试

%timeit
测试

import pandas as pd
import os
from pathlib import Path

# sample dataframe with 30000 rows
df = pd.DataFrame({'Sr No': [18, 19, 20],
                   'Email': ['[email protected]', '[email protected]', '[email protected]'],
                   'filename': [r'C:/Users\Test.csv', r'C:/Users\Test1.csv', r'C:/Users\Test1.csv']})
df = pd.concat([df] * 10000, ignore_index=True)

# timeit tests
%timeit df["filename"].apply(lambda path: Path(path).name)
%timeit df["filename"].apply(os.path.basename)
%timeit df["filename"].apply(lambda path: os.path.basename(path))
%timeit df['filename'].str.split('\\', expand=True).iloc[:, -1]

结果

67.4 ms ± 1.72 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
43 ms ± 1.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
43 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
15.2 ms ± 216 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

0
投票

您需要通过重新定义来修改现有列。首先用 pandas 阅读它:

import pandas as pd
df = pd.read_csv('file_path\file_name.csv')
df['filename'] = df['filename'].map(lambda x: x.split('\\')[-1][:-4])
df = df.drop_duplicates()

这会产生作为数据框的预期结果,因此您所缺少的只是将其保存回 csv/excel:

df.to_excel('file_path\new_file_name.xlsx')

或 csv:

df.to_csv('file_path\new_file_name.csv')

0
投票

使用

将 excel 文件读入 pandas 数据框
import pandas as pd
df = pd.read_excel("your excel file location")

然后使用apply函数对整列进行一次操作如下

def get_filename(path):
    temp_str = path.split('/')
    return temp_str[-1]

df["filename"] = df["filename"].apply(get_filename)

0
投票

除了上述答案,您还可以使用字符串方法:

df['filename'] = df['filename'].str.split('/')[-1]

不确定哪个最快。


0
投票

假设您在给定的文件名列中有固定长度的目录:

# created dataframe for example
df = pd.DataFrame({'Email':['[email protected]','[email protected]','[email protected]'],
                   'filename':['c:/users\test.csv','c:/users\test1.csv','c:/users\test1.csv']} )   # dataframe

# will create new column with file name only
df['only_filename'] = [(path.encode('unicode_escape')[9:]).decode("utf-8") for path in df['filename']]
 
© www.soinside.com 2019 - 2024. All rights reserved.