我有一个带有文件路径列的DataFrame。
我想将其更改为仅文件名。
我的DataFrame看起来像:
df = pd.DataFrame({
'Sr No': [18, 19, 20],
'Email': ['Test@test.com', 'Test@test.com', 'Test@test.com'],
'filename': [r'C:/UsersTest.csv', r'C:/UsersTest1.csv',
r'C:/UsersTest1.csv']
})
序号 | 电子邮件 | 文件名 |
---|---|---|
18 | Test@test.com | C:\Users\Test.csv |
19 | Test@test.com | C:\Users\Test1.csv |
20 | Test@test.com | C:\Users\Test1.csv |
使用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 Test@test.com C:/UsersTest.csv
1 19 Test@test.com C:/UsersTest1.csv
2 20 Test@test.com C:/UsersTest1.csv
>>> df["filename"] = df["filename"].apply(os.path.basename)
>>> df
Sr No Email filename
0 18 Test@test.com Test.csv
1 19 Test@test.com Test1.csv
2 20 Test@test.com Test1.csv
pathlib
模块中还有一个使用Path('C:/UsersTest.csv').name
的选项,但这比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': ['Test@test.com', 'Test@test.com', 'Test@test.com'],
'filename': [r'C:/UsersTest.csv', r'C:/UsersTest1.csv', r'C:/UsersTest1.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)
您需要通过重新定义来修改现有列
import pandas as pd
df = pd.read_csv('file_pathfile_name.csv')
df['filename'] = df['filename'].map(lambda x: x.split('\')[-1][:-4])
df = df.drop_duplicates()
这将产生作为数据帧的预期结果,因此您所缺少的只是将其保存回csv/excel:
df.to_excel('file_pathnew_file_name.xlsx')
或csv:
df.to_csv('file_pathnew_file_name.csv')
使用将excel文件读取到pandas数据帧中
import pandas as pd
df = pd.read_excel("your excel file location")
然后使用应用函数对整列执行一个操作,如下所示
def get_filename(path):
temp_str = path.split('/')
return temp_str[-1]
df["filename"] = df["filename"].apply(get_filename)
除了上面的答案,您还可以使用字符串方法:
df['filename'] = df['filename'].str.split('/')[-1]
不确定哪一个最快。
假设文件名列中的目录长度是固定的:
# created dataframe for example
df = pd.DataFrame({'Email':['test@gmail.com','test@gmail.com','test@gmail.com'],
'filename':['c:/userstest.csv','c:/userstest1.csv','c:/userstest1.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']]