我有一个带有文件路径列的 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 |
简而言之,我的输出应该是这样的:
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])
但是它只对一个路径有用,如何应用到整个列?
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)
您需要通过重新定义来修改现有列。首先用 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')
使用
将 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)
除了上述答案,您还可以使用字符串方法:
df['filename'] = df['filename'].str.split('/')[-1]
不确定哪个最快。
假设您在给定的文件名列中有固定长度的目录:
# 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']]